xo310
asked on
How to get the handle of a control we know its identifier
Hi,
A control in an external application. Its "Control ID" in WinDowse is 000007D5.
Can we get the handle of a control using its Control ID?
We already know the parent window's handle.
Here is some info obtained from WinDowse
*** Window Information ************************** ********** ********** ********** *
Text
Process ID 00000F24
App instance 00400000
Handle 004704A6
Parent handle 00600376
Control ID 000007D5
Function 00000000
Menu handle 00000000
Coords in parent left:230, top:370, right:311, bottom:398
Coords in screen left:440, top:494, right:521, bottom:522
Window size width:81, height:28
Client area size width:81, height:28
Style 40000004
Extended style 00000000
ws_overlapped | ws_child | ws_ex_left | ws_ex_ltrreading | ws_ex_rightscrollbar
*** Class Information ************************** ********** ********** ********** **
Name AfxWnd42s
Function 77D45C55
Icon 00000000
Small icon 00000000
Cursor 00010011
Bkg brush 00000000
Module handle 00400000
Style 0000000B
cs_vredraw | cs_hredraw | cs_dblclks
*** Parents ************************** ********** ********** ********** ********** **
# Handle Class name Text
001 00600376 #32770 Beauty & the Beast
*** Children ************************** ********** ********** ********** ********** *
# Handle Class name Text
*** Digger ************************** ********** ********** ********** ********** ***
# Handle Class name Text
001 00600376 #32770 Beauty & the Beast
002 00010088 SysListView32 FolderView
003 00010086 SHELLDLL_DefView
004 00010084 Progman Program Manager
A control in an external application. Its "Control ID" in WinDowse is 000007D5.
Can we get the handle of a control using its Control ID?
We already know the parent window's handle.
Here is some info obtained from WinDowse
*** Window Information **************************
Text
Process ID 00000F24
App instance 00400000
Handle 004704A6
Parent handle 00600376
Control ID 000007D5
Function 00000000
Menu handle 00000000
Coords in parent left:230, top:370, right:311, bottom:398
Coords in screen left:440, top:494, right:521, bottom:522
Window size width:81, height:28
Client area size width:81, height:28
Style 40000004
Extended style 00000000
ws_overlapped | ws_child | ws_ex_left | ws_ex_ltrreading | ws_ex_rightscrollbar
*** Class Information **************************
Name AfxWnd42s
Function 77D45C55
Icon 00000000
Small icon 00000000
Cursor 00010011
Bkg brush 00000000
Module handle 00400000
Style 0000000B
cs_vredraw | cs_hredraw | cs_dblclks
*** Parents **************************
# Handle Class name Text
001 00600376 #32770 Beauty & the Beast
*** Children **************************
# Handle Class name Text
*** Digger **************************
# Handle Class name Text
001 00600376 #32770 Beauty & the Beast
002 00010088 SysListView32 FolderView
003 00010086 SHELLDLL_DefView
004 00010084 Progman Program Manager
what about using FindWindow() and FindWindowEx() functions?
ASKER
there are many controls that share the same class name with the control I need.
but for a unique control in the application like a richedit I use this at the moment
FUNCTION FindRichEditHwnd: Integer;
VAR
Wnd: Cardinal;
{the parent handle}
wnd1: Integer;
{The richedit handle}
Txt: PChar;
BEGIN
Wnd := 0;
GetMem(Txt, 256);
REPEAT
Wnd := FindWindowEx(0, Wnd, '#32770', NIL);
GetWindowText(Wnd, Txt, 256);
BEGIN
IF (AnsiContainsText(Txt, 'Good Luck') = True) THEN
BEGIN
Break;
END;
END;
UNTIL Wnd = 0;
FreeMem(Txt);
IF Wnd <> 0 THEN
BEGIN
wnd1 := FindWindowEx(Wnd, 0, 'RICHEDIT', NIL);
Hwnd := wnd1
END
ELSE
BEGIN
Form1.Caption := 'could not get handle';
END;
END;
but for a unique control in the application like a richedit I use this at the moment
FUNCTION FindRichEditHwnd: Integer;
VAR
Wnd: Cardinal;
{the parent handle}
wnd1: Integer;
{The richedit handle}
Txt: PChar;
BEGIN
Wnd := 0;
GetMem(Txt, 256);
REPEAT
Wnd := FindWindowEx(0, Wnd, '#32770', NIL);
GetWindowText(Wnd, Txt, 256);
BEGIN
IF (AnsiContainsText(Txt, 'Good Luck') = True) THEN
BEGIN
Break;
END;
END;
UNTIL Wnd = 0;
FreeMem(Txt);
IF Wnd <> 0 THEN
BEGIN
wnd1 := FindWindowEx(Wnd, 0, 'RICHEDIT', NIL);
Hwnd := wnd1
END
ELSE
BEGIN
Form1.Caption := 'could not get handle';
END;
END;
ASKER
There are 15 controls with class name:AfxWnd42s int eh same window
but there IDs or identifiers are different
but there IDs or identifiers are different
ASKER
their
what about captions? do they have any?
ASKER
They do have text on them but does not appear when mouse is over them using Windowse.
I want the handle to try getwindowtext with them.
I want the handle to try getwindowtext with them.
Is that program (you want to interact with) freely available somewhere? I could download it and try to help...
ASKER
yes it is empirepoker.com
you dont have to register to see tables.
the controls I am talking about are player names.
thanks alot
you dont have to register to see tables.
the controls I am talking about are player names.
thanks alot
ASKER
I am also trying EnumChilWindow but this code keeps telling me "variable required" with the cursor after "addr(EnumChildWindowFunc) "
procedure TForm1.Button4Click(Sender : TObject);
begin
Memo1.Clear;
EnumChildWindows(ParentGam eHwnd, addr(EnumChildWindowFunc), Integer(memo1.Lines));
end;
Function TForm1.EnumChildWindowFunc (wnd: HWND; Lines: TStrings): BOOL; stdcall;
var
buf, Caption: array[0..255] of char;
Begin
Result := True;
GetClassName(wnd, buf, SizeOf(buf) - 1);
SendMessage(wnd, WM_GETTEXT, 256, Integer(@Caption));
Lines.Add(Format('ID: %d, ClassName: %s, Caption: %s',
[GetDlgCtrlID(wnd), buf, Caption]));
end;
procedure TForm1.Button4Click(Sender
begin
Memo1.Clear;
EnumChildWindows(ParentGam
end;
Function TForm1.EnumChildWindowFunc
var
buf, Caption: array[0..255] of char;
Begin
Result := True;
GetClassName(wnd, buf, SizeOf(buf) - 1);
SendMessage(wnd, WM_GETTEXT, 256, Integer(@Caption));
Lines.Add(Format('ID: %d, ClassName: %s, Caption: %s',
[GetDlgCtrlID(wnd), buf, Caption]));
end;
ASKER
ok forget about the new Question it si because it should be a function not a method
not sure about what you might need here.. . but if you have an ID number for a Control, you can get it's Handle from it's parent with the GetDlgItem( ) function. . . .
hScroll := GetDlgItem(hParentWnd, ID_Number);
but in your comment above you have
Handle 004704A6
Parent handle 00600376
Control ID 000007D5
wouldn'i the control handle be -
$4704A6
hScroll := GetDlgItem(hParentWnd, ID_Number);
but in your comment above you have
Handle 004704A6
Parent handle 00600376
Control ID 000007D5
wouldn'i the control handle be -
$4704A6
ASKER
the handle will change from my pc to another
I tried it with the resulting name being "S‹Ø‹ÃèÏ" which is meaningless there must be something wrong
here is the code:
procedure TForm1.Button4Click(Sender : TObject);
var
h1:cardinal;
txt:pchar;
begin
h1:=GetDlgItem(GameHwnd,$7 D5);//Game Hwnd is the parent window handle coming from another function
getwindowtext(h1,txt,100);
edit10.Text:=txt;
end;
I tried it with the resulting name being "S‹Ø‹ÃèÏ" which is meaningless there must be something wrong
here is the code:
procedure TForm1.Button4Click(Sender
var
h1:cardinal;
txt:pchar;
begin
h1:=GetDlgItem(GameHwnd,$7
getwindowtext(h1,txt,100);
edit10.Text:=txt;
end;
You should allocate memory before using txt in getwindowtext() function. Try this:
procedure TForm1.Button4Click(Sender : TObject);
var
h1:cardinal;
txt:pchar;
begin
h1:=GetDlgItem(GameHwnd,$7 D5);
GetMem(txt, 100); //allocate memory
getwindowtext(h1,txt,100);
edit10.Text:=txt;
FreeMem(txt); //free memory, when it is not needed anymore
end;
procedure TForm1.Button4Click(Sender
var
h1:cardinal;
txt:pchar;
begin
h1:=GetDlgItem(GameHwnd,$7
GetMem(txt, 100); //allocate memory
getwindowtext(h1,txt,100);
edit10.Text:=txt;
FreeMem(txt); //free memory, when it is not needed anymore
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
yes it seems as you said. I used the handle i get from Windowse directly and no text came out.
so what do you advice?
No need for a full answer as I know this deserves more than 500 points:)
did you find any point where I can start from?
so what do you advice?
No need for a full answer as I know this deserves more than 500 points:)
did you find any point where I can start from?
ASKER
what made me think it is that class name is that the controls IDs associated with go from D0 to D9 starting from the dealer. As if these controls hold information about players.
ASKER
I enumerated all child windows of the parent and showed thier captions but there was not clue about player names.
I found some comments on the web:
"The AfxWnd42s class means the window is not an edit
control, and the text is painted by the application. The only possible
approach (not too practical) is to grab the painted image and employ
optical character recognition algorithms."-- Scott McPhillips [VC++ MVP]
I found some comments on the web:
"The AfxWnd42s class means the window is not an edit
control, and the text is painted by the application. The only possible
approach (not too practical) is to grab the painted image and employ
optical character recognition algorithms."-- Scott McPhillips [VC++ MVP]
All these player names are stored somewhere in memory. I have seen some programs that find some user-defined value in memory that belongs to some user-specified process, so I think it must be possible to read these player names from memory, but I don't know - how. I haven't worked with memory that seriously.