WM_GETTEXT problem

Hi Everyone,
I have program that should read both textboxes and textlabels from another program. I'm retrieving the handle for the controls with EnumWindows and EnumChildWindows. First I tried the GetWindowsText which worked fine, but not with the Edit Boxes. So I'm now trying to use the WM_GETTEXT directly but with no better success.. I'm not getting any text at all..

Here is the code used:
function EnumTextChildProc(AHandle: hWnd; AnObject: TObject): BOOL; stdcall;
var
  caption: array[0..3000] of Char;
  s: string;
begin
  Result := True;
  SendMessage(AHandle, WM_GETTEXT, Sizeof(caption), integer(@caption));
  s := Caption;
  ShowMessage(s);
end;


Any solutions or workarounds for this problem?

(using Win 8 and Delphi XE3)
hakanfaAsked:
Who is Participating?
 
ThommyConnect With a Mentor Commented:
What is the difference between PostMessage and SendMessage?

For WM_GETTEXT you should prefer using SendMessage (synchronous version) to make sure that your program waits until the message has been proccessed.

PostMessage just places the message into the message queue and returns regardless if the message has been processed or not. Especially in case of high message loads there is no garantuee that the return parameter of the Postmessage function is correctly set in time.

Postmessage is good in multithreading apps: with PostMessage you can deliver messages to any thread in the system without waiting for the result. The message is just placed onto the message queue of the receiving thread and stays there until the receiving thread comes to life. At that time the message is handled. All that time your thread continues to run...
0
 
Sinisa VukCommented:
http://www.delphifaq.com/faq/delphi/windows_GUI/f451_0.htm

Your example works ok for me when used as:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  EnumChildWindows(Self.Handle, @EnumTextChildProc, 0);
end;

Open in new window

(i put edit and button component on form)

http://borland.public.delphi.winapi.narkive.com/Qw0wAIR1/wm-gettext-doesn-t-work-in-the-icq-chat-window
0
 
ThommyCommented:
Download Winhandles.zip

Try out this wonderful example of getting text from any control of all running processes and applications...
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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.

 
ThommyCommented:
Check my below demo code to see how to get edit text from another program using Windows message WM_GETTEXT... (Finding child windows in other applications by ClassName)

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    function nGetChildHandle: Integer;
  public
    { Public-Deklarationen }
  end;

function EIFindChildWindow(hwndParent: HWnd; ClassName: PChar): HWnd;
function EIGetWindowClass(const nHandle: HWnd): string;

var
  Form1: TForm1;

implementation

var
  hwndFindChildWindow : HWND;


{$R *.dfm}

function EnumTextChildProc(AHandle: hWnd): BOOL; stdcall;
var
  AText: array[0..255] of Char;
  s: string;
begin
  Result := True;
  PostMessage(AHandle, WM_GETTEXT, Sizeof(AText), integer(@AText));
  s := strpas(AText);
  ShowMessage(s);
end;

function GetTextFromHandle(wndhandle: HWnd): string;
var
 textlength: integer;
 text: PChar;
begin
   result := '';
   if wndhandle = 0 then Exit;
   textlength := SendMessage(wndhandle, WM_GETTEXTLENGTH, 0, 0);
   if textlength <> 0 then
     begin
       GetMem(Text, textlength+1);
       SendMessage(wndhandle, WM_GETTEXT, textlength+1, Integer(text));
       Result := text;
       FreeMem(text);
     end;

end;

function EIGetWindowClass(const nHandle: HWnd): string;
var
  szClassName: array[0..255] of char;
begin
  GetClassName(nHandle, szClassName, 255);
  Result := szClassName;
end;

function EnumWindowsForFindChildWindowProc(WHandle: HWND; lParam: LPARAM): BOOL; export; stdcall;
const
  MAX_WINDOW_NAME_LEN = 80;
var
  sTargetClassName: string;
  nHandle: HWnd;
  sCurrClassName: string;
  bResult: Boolean;
begin
  if (hwndFindChildWindow<>0) then
    exit;
  sTargetClassName := PChar(lParam);
  sCurrClassName := EIGetWindowClass(WHandle);
  bResult := CompareText(sCurrClassName, sTargetClassName) = 0;
  If (bResult) then
    hwndFindChildWindow := WHandle
  else
    EIFindChildWindow(WHandle, PChar(lParam));
end;

function EIFindChildWindow(hwndParent: HWnd; ClassName: PChar) : HWnd;
begin
  try
    EnumChildWindows(hwndParent, @EnumWindowsForFindChildWindowProc, LongInt(PChar(ClassName)));
    Result := hwndFindChildWindow;
  except
    on Exception do
      Result := 0;
  end;
end;

function TForm1.nGetChildHandle: Integer;
var
  nParentHandle: HWnd;
  nChildHandle: HWnd;
begin
  //Find parent window
  nParentHandle := FindWindow(nil, PChar('Your window title'));
  if nParentHandle = 0 then
    raise Exception.Create('Couldn''t find the main window !');

  //Find child window (TEdit)
  nChildHandle := EIFindChildWindow(nParentHandle, PChar('TEdit'));
  if nChildHandle = 0 then
    raise Exception.Create('Couldn''t find the child window !');

  Result := nChildHandle;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  TheChildHandle: hwnd;
begin
  TheChildHandle:=nGetChildHandle;
end;

end.

Open in new window

0
 
hakanfaAuthor Commented:
Hi Tommy, thanks for the pice of code. Works fine with small modifications for own needs. Though one question, you use both send-message and post-message command, any specific reason for that? Anyhow, works fine, thanks!

-Hokki
0
 
hakanfaAuthor Commented:
Excellent, thank you very much!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.