Solved

Button caption from a Windows dll? How?

Posted on 2004-08-16
8
256 Views
Last Modified: 2010-04-05
Hi all!

How can i read a control text from a Windows dll? For example i'd like to get the caption of a dialog button. Windows\System32\msgina.dll (under XP)

Dialog\1800\

CONTROL "&Change Password...", 1803, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 98, 84, 14 (with ResourceHacker, in DIALOGEX)

I want to read this button's caption into an Edit.

Thanks!

(Please show me some source code)
0
Comment
Question by:rogerrr
8 Comments
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 11808458
procedure TForm1.Button1Click(Sender: TObject);
var
  buffer: array[0..255] of Char;
  DLL_HANDLE : THandle;
begin
  DLL_HANDLE := LoadLibrary('msgina.dll');
  Loadstring(DLL_HANDLE, 1, @buffer, 255);  //1 = first string
  label1.Caption := StrPas(buffer);
end;
0
 

Author Comment

by:rogerrr
ID: 11810214
Thanks, but this code works only with Stringtable resources...
0
 
LVL 3

Expert Comment

by:Tyrsis
ID: 11814922
I would suggest looking at the source code for the Resource Explorer and the Resource Utility components that are on the following page:

http://www.wilsonc.demon.co.uk/delphi.htm

All source code is included from that web page on how to find and read resources from DLL/EXEs in Delphi.  And it is all free.

I hope this helps put you on the right track.

Tyrsis
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 7

Expert Comment

by:LRHGuy
ID: 11817276
Try this...you'll have to fill in a few items...

const
  Flags=format_message_from_hmodule or format_message_allocate_buffer;
  dllname='netmsg.dll';  //name of DLL to get message from
  msgno=12; //message number
var
  DLL:HModule;
  Msg:pChar;
begin
  dll:=loadlibraryex(dllname,0,load_library_as_datafile);
  if dll<>0 then begin
    if formatmessage(flags,pointer(dll),msgno,0,@msg,0,nil)>0 then begin
      showmessage(msg);
      localfree(cardinal(msg));
    end;
    freelibrary(dll);
  end;
0
 

Author Comment

by:rogerrr
ID: 11822214
Hi all!

It as good as done!:-)

I found a code but this doesn't works if the dialog type is DIALOGEX.

Code:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

  type
  TDialogItem = record
    ControlID: dWord;
    Title: WideString;
  end;


type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FDlgItems: array of TDialogItem;
    procedure ReadDialogItems(Stream: TStream);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function ReadChar(Stream: TStream; var Ch: WideChar): Boolean;
begin
  Stream.ReadBuffer(Ch, SizeOf(Ch));
  Result := Word(Ch) <> $0000;
end;

function ReadString(Stream: TStream; var StrBuf: WideString): Boolean;
var
  Ch: WideChar;
begin
  Result := True;
  StrBuf := '';
  if ReadChar(Stream, Ch) then begin
    Result := Word(Ch) <> $FFFF;
    if Result then begin
      StrBuf := StrBuf + Ch;
      while (Stream.Position <> Stream.Size) and ReadChar(Stream, Ch) do
        StrBuf := StrBuf + Ch;
    end
    else begin
      SetLength(StrBuf, 1);
      ReadChar(Stream, StrBuf[1]);
    end;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  msgina: HModule;
  Stream: TStream;
begin
  msgina := LoadLibrary('msgina.dll');
  try
    Stream := TResourceStream.CreateFromID(msgina, 1800, RT_DIALOG);
    try
      ReadDialogItems(Stream);
    finally
      Stream.Free;
    end;
  finally
    FreeLibrary(msgina);
  end;
  for I := 0 to Length(FDlgItems) - 1 do
    if FDlgItems[I].ControlID = 1803 then begin
      label1.caption:=FDlgItems[0].Title;
      Break;
    end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
Finalize(FDlgItems);
end;

procedure TForm1.ReadDialogItems(Stream: TStream);
var
  DataSize: Word;
  DlgItem: TDlgItemTemplate;
  DlgTemplate: TDlgTemplate;
  I: Integer;
  StrBuf: WideString;
begin
  Stream.ReadBuffer(DlgTemplate, SizeOf(DlgTemplate));
  ReadString(Stream, StrBuf);
  ReadString(Stream, StrBuf);
  ReadString(Stream, StrBuf);
  if (DlgTemplate.style and DS_SETFONT) <> 0 then begin
  Stream.Seek(SizeOf(SmallInt), soFromCurrent);
    ReadString(Stream, StrBuf);
  end;
  Finalize(FDlgItems);
  for I := 0 to DlgTemplate.cdit - 1 do begin
    SetLength(FDlgItems, I + 1);
    Stream.Seek(Stream.Position mod SizeOf(DWORD), soFromCurrent);
    Stream.ReadBuffer(DlgItem, SizeOf(DlgItem));
    FDlgItems[I].ControlID:= DlgItem.id;
   ReadString(Stream, StrBuf);
    ReadString(Stream, FDlgItems[I].Title);
   Stream.ReadBuffer(DataSize, SizeOf(DataSize));
    Stream.Seek(DataSize, soFromCurrent);
  end;
end;

end.



2500 is a simple DIALOG. I changed 1800 to 2500 and 1803 to 2501. Label1.Caption will be -->OK (Under XP)



What's the problem if i read a DIALOGEX type????????
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 13404446
PAQed with points refunded (110)

modulo
Community Support Moderator
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

827 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question