This is an old revision of the document!
Finding a Window Handle
Use function FindWindow()
to get a window handle. If a child window is required, use FindWindowEx()
.
Example:
procedure TfrmMain.btnGetWinInfoClick(Sender: TObject); var i: integer; lWnd: THandle; AppTitle, WndName, ClassName: string; Title: array[0..255] of char; pid: dword; begin // get a top-level form ClassName := 'TForm'; // or TPanel, TButton, etc. lWnd := FindWindow(PAnsiChar(ClassName), nil); if lWnd > 0 then LogWinInfo(lWnd, 'btnGetWinInfoClick() found window'); // get a child window ClassName := 'TForm'; WndName := 'My Window'; lWnd := FindWindowEx(FindWindow('TApplication', nil) {ParentWinHwnd where to start search}, 0 {ChildWinHwnd where to start search}, PAnsiChar(ClassName) {ClassName to search}, PAnsiChar(WndName) {WindowName to search} ); if lWnd > 0 then LogWinInfo(lWnd, 'btnGetWinInfoClick() found window'); // get child windows with the specified class and/or window title GetWindowText(GetHandle('TApplication' {ClassName}, nil {Window Title to search}), Title {Title to retrieve}, 255); end;
A routine that provides a handle for a child window or control:
function GetHandle(ClassName, WindowName: PAnsiChar): THandle; begin // find specified form Result := FindWindow(ClassName, WindowName); LogWinInfo(Result, 'GetHandle()'); // find child windows and list them (log) EnumChildWindows(Result, @GetMyChildWindow, 0); Result := GetWindow(Result, GW_CHILD); LogWinInfo(Result, 'GetHandle()'); Result := GetWindow(Result, GW_CHILD); LogWinInfo(Result, 'GetHandle()'); Result := GetWindow(Result, GW_HWNDNEXT); LogWinInfo(Result, 'GetHandle()'); end;
A sample callback function used by EnumWindows()
or EnumChildWindows()
:
function GetMyChildWindow(Handle: HWND; LParam: longint): bool; stdcall; begin LogWinInfo(Handle, 'GetMyChildWindow()'); result := True; end;
Use GetClassName()
and GetWindowText()
to get more information about a handle:
procedure LogWinInfo(WinHandle: THandle; Msg: string); var WindowTitle, ClassName: array [0..255] of char; begin GetClassName(WinHandle, ClassName, 255); GetWindowText(WinHandle, WindowTitle, 255); DebugStr(format('%s: H = [%10.d], Class = [%-20.20s], Window = [%s].', [Msg, WinHandle, ClassName, WindowTitle])); end;
TWinControl.Parent vs TWinControl.ParentWindow
From Delphi User Documentation: 1)
ParentWindow
refers to the window handle that underlies the parent control. To designate a non-VCL control as a parent, assign that control’s handle toParentWindow
. This assignment causes the control to be moved into the parent’s screen area. SettingParentWindow
has no effect ifParent
is notnil
(Delphi) or NULL (C++). <p>TActiveXControl objects useParentWindow
to insert a control in an ActiveX container window.ParentWindow
is set automatically when a control is constructed with a call toCreateParented()
(Delphi) or the appropriate overloaded constructor (C++).
- Some controls (such as ActiveX controls) are contained in native windows rather than in a parent VCL control. For these controls, the value of
Parent
isnil
(Delphi) or NULL (C++) and theParentWindow
property specifies the window. 2)
Finding a Control/Window from a Handle
Use FindControl()
to get the VCL control given a previously retrieved handle.
Example:
const MAIN_WND_CLASS = 'TAppBuilder'; procedure TTBCConfig.SetGradient(const aVisible: Boolean); var i: Integer; lWinCtrl: TWinControl; lWnd: Hwnd; lCtrlBar: TControlBar; begin lWnd := FindWindow(MAIN_WND_CLASS, nil); // find the required window lWinCtrl := FindControl(lWnd); // find the control using the given handle // do some work with the control now if lWinCtrl <> nil then begin lCtrlBar := nil; // find the control bar on the app builder form for i := 0 to lWinCtrl.ControlCount - 1 do begin if lWinCtrl.Controls[i] is TControlBar then begin lCtrlBar := TControlBar(lWinCtrl.Controls[i]); break; end; end; end; end;