Working with Components and Windows

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 to ParentWindow. This assignment causes the control to be moved into the parent’s screen area. Setting ParentWindow has no effect if Parent is not nil (Delphi) or NULL (C++). <p>TActiveXControl objects use ParentWindow to insert a control in an ActiveX container window. ParentWindow is set automatically when a control is constructed with a call to CreateParented() (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 is nil (Delphi) or NULL (C++) and the ParentWindow 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;
1)
“ParentWindow property (TWinControl)”, Delphi Help, Borland
2)
“Parent property (TControl)”, Delphi Help, Borland