Show the Windows Hierarchy (Views: 2141)
Problem/Question/Abstract: 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: //--- function GetWinInfo(h: HWND): string; var tmp: PChar; begin //Get the HWND value in hex and Decimal result := inttohex(h, 8); result := result + ' (' + inttostr(h) + ')'; //Get ClassName, and Window Caption //Allow upto 255 Characters GetMem(tmp, 255); GetClassName(h, tmp, 255); result := result + ': ' + tmp; tmp[0] := #0; GetWindowText(h, tmp, 255); result := result + ' - ' + tmp; FreeMem(tmp); end; procedure GetChildren(h: HWND; n: TTreeNode; T: TTreeview); var Childhw: HWND; ChildNode: TTreeNode; begin //Get any Children ChildHw := GetWindow(h, GW_CHILD); while Childhw > 32 do begin //Add this Handle ChildNode := T.Items.AddChild(n, GetWinInfo(Childhw)); //Get any Children - Recursive call... GetChildren(Childhw, ChildNode, T); //Get the next window Childhw := GetWindow(Childhw, GW_HWNDNEXT); end; end; procedure GetWinTree(T: TTreeview); var hw: HWND; node: TTreeNode; begin //Loop through all Top Level Windows hw := FindWindow(nil, nil); while hw > 32 do begin //Add this Handle node := t.items.Add(nil, GetWinInfo(hw)); //Get any Children GetChildren(hw, Node, T); //Get the next window hw := GetWindow(hw, GW_HWNDNEXT); end; end; //--- Then put something like this on the ButtonClick Event Handler... procedure TForm1.Button1Click(Sender: TObject); begin TreeView1.Items.clear; GetWinTree(TreeView1); 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... |