Solved

WM_GETTEXT problem

Posted on 2013-01-01
6
1,394 Views
Last Modified: 2013-01-03
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)
0
Comment
Question by:hakanfa
  • 3
  • 2
6 Comments
 
LVL 26

Expert Comment

by:Sinisa Vuk
ID: 38735053
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
 
LVL 19

Expert Comment

by:Thommy
ID: 38736651
Download Winhandles.zip

Try out this wonderful example of getting text from any control of all running processes and applications...
0
 
LVL 19

Expert Comment

by:Thommy
ID: 38739474
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:hakanfa
ID: 38740512
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
 
LVL 19

Accepted Solution

by:
Thommy earned 500 total points
ID: 38741581
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
 

Author Closing Comment

by:hakanfa
ID: 38741617
Excellent, thank you very much!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Machine not responding during CopyFile() 3 88
Delphi - replicating a form 8 62
how to update exe applicatio from internet ? 6 67
JAudiorecorder record freezing the app 29 59
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Delivering innovative fully-managed cloud services for mission-critical applications requires expertise in multiple areas plus vision and commitment. Meet a few of the people behind the quality services of Concerto.
A company’s greatest vulnerability is their email. CEO fraud, ransomware and spear phishing attacks are the no1 threat to a company’s security. Cybercrime is responsible for the largest loss of money to companies today with losses projected to r…

919 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now