Author: Duncan Parsons
There are times when you could do with knowing what different window Handles are
for testing messaging apps, etc. Without Loading WinSight (with all it's
overheads), or getting WinSpy++, here is a simple digest of Handles, Class Names,
and Window Captions.
Answer:
On a Form, place a TreeView Control, and a Button.
Paste in the following 3 procedures/ functions into the implementation Code:
1 //---
2
3 function GetWinInfo(h: HWND): string;
4 var
5 tmp: PChar;
6 begin
7 //Get the HWND value in hex and Decimal
8 result := inttohex(h, 8);
9 result := result + ' (' + inttostr(h) + ')';
10 //Get ClassName, and Window Caption
11 //Allow upto 255 Characters
12 GetMem(tmp, 255);
13 GetClassName(h, tmp, 255);
14 result := result + ': ' + tmp;
15 tmp[0] := #0;
16 GetWindowText(h, tmp, 255);
17 result := result + ' - ' + tmp;
18 FreeMem(tmp);
19 end;
20
21 procedure GetChildren(h: HWND; n: TTreeNode; T: TTreeview);
22 var
23 Childhw: HWND;
24 ChildNode: TTreeNode;
25 begin
26 //Get any Children
27 ChildHw := GetWindow(h, GW_CHILD);
28 while Childhw > 32 do
29 begin
30 //Add this Handle
31 ChildNode := T.Items.AddChild(n, GetWinInfo(Childhw));
32 //Get any Children - Recursive call...
33 GetChildren(Childhw, ChildNode, T);
34 //Get the next window
35 Childhw := GetWindow(Childhw, GW_HWNDNEXT);
36 end;
37 end;
38
39 procedure GetWinTree(T: TTreeview);
40 var
41 hw: HWND;
42 node: TTreeNode;
43 begin
44 //Loop through all Top Level Windows
45 hw := FindWindow(nil, nil);
46 while hw > 32 do
47 begin
48 //Add this Handle
49 node := t.items.Add(nil, GetWinInfo(hw));
50 //Get any Children
51 GetChildren(hw, Node, T);
52 //Get the next window
53 hw := GetWindow(hw, GW_HWNDNEXT);
54 end;
55 end;
56
57 //---
Then put something like this on the ButtonClick Event Handler...
58
59 procedure TForm1.Button1Click(Sender: TObject);
60 begin
61 TreeView1.Items.clear;
62 GetWinTree(TreeView1);
63 end;
You will then have a List of All current Window Handles, with all Child Windows
listed with then in their correct places.
This could be expanded with searching/ grouping of like classes, etc. But I leave
that to you, here is a starting place.
I have used this at various times to get M$ Class names. For instance, if you are using DAO to automatically configure an Access DB to point it's linked tables at a particular SQL Server, I used this to get the Class name of the SQL Server Login form, so that I could search for it and click the OK button before the user gets to it...
|