0

I am developing an application in Delphi XE2 which inspects, through the functions EnumWindows and EnumChildWindows a window of a running application also written in Delphi.

This is the main code (adapted from an example: http://www.swissdelphicenter.ch/torry/showcode.php?id=410)

function EnumChildWindowsProc(Wnd: HWnd; Form: TForm1): Bool; export;
  {$ifdef Win32} stdcall; {$endif}
var
  Buffer: array[0..99] of Char;
begin
  GetWindowText(Wnd, Buffer, 100);

  if StrPas(Buffer) = '' then Buffer := 'Empty';
  new(AWindows);
  with AWindows^ do
  begin
    WindowHandle := Wnd;
    WindowText   := StrPas(Buffer);
  end;

  CNode := Form1.TreeView1.Items.AddChildObject(PNode,
               AWindows^.WindowText + ':' +
               IntToHex(AWindows^.WindowHandle, 8), AWindows);

  if GetWindow(Wnd, GW_CHILD) = 0 then
  begin
    PNode := CNode;
    Enumchildwindows(Wnd, @EnumChildWindowsProc, 0);
  end;
  Result := True;
end;

function EnumWindowsProc(Wnd: HWnd; Form: TForm1): Bool;
  export; {$ifdef Win32} stdcall; {$endif}
var
  Buffer: array[0..99] of Char;
begin
  GetWindowText(Wnd, Buffer, 100);

  if StrPas(Buffer) = '' then Buffer := 'Empty';
  new(AWindows);
  with AWindows^ do
  begin
    WindowHandle := Wnd;
    WindowText   := StrPas(Buffer);
  end;

  if Pos(Form1.edAppToFind.Text,AWindows^.WindowText) > 0 then // <- inspect child only for my Application
  begin
    PNode := Form1.TreeView1.Items.AddObject(nil, AWindows^.WindowText + ':' +
      IntToHex(AWindows^.WindowHandle, 8), AWindows);
    EnumChildWindows(Wnd, @EnumChildWindowsProc, 0);
  end;
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumWindows(@EnumWindowsProc, self.Handle);
end;

Everything works well, except for the object TGroupBox after which the recursion stops. But control TGroupBox contains inside other elements (TLabel).

In fact, even writing a simple application in Delphi, by including in the Form a TGroupBox and then into the TGroupBox a TLabel, launching the Application and inspecting it with Spy++ (or with the Tool Autoit AU3Info) you can not enter into the TGroupBox: the TLabel inside is not inspected.

Is there a way to find TLabel control within the TGroupBox?

Federico Zancan
  • 4,846
  • 4
  • 44
  • 60
AndreaBoc
  • 3,077
  • 2
  • 17
  • 22

1 Answers1

6

This is not an issue with the group box control. The issue is that the TLabel control is not windowed. There's no window handle associated with it and so it cannot be found by Spy++, EnumChildWindows etc.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • in fact, TLabel is not enumerated, the problem isn't TComboBox but TLabel... There is way to find Labels inside Window? – AndreaBoc Sep 19 '13 at 11:13
  • 1
    That's precisely what I'm telling you. Since `TLabel` has not window handle, external tools that rely on `EnumChildWindows` (like AutoIT and Spy++) cannot find it. The standard way to expose your UI for automation is with an automation interface. The current standard is UIAutomation. – David Heffernan Sep 19 '13 at 11:16
  • I have to inspect a third party application, so if the application contain simple TLabel there is no way to read text on it with EnumWindow or EnumChildwindow, right? there is other way to read it? – AndreaBoc Sep 19 '13 at 11:52
  • Unless the application exposes an automation interface, you are stuck. Talk to the vendor. I think I already answered the question that you asked. – David Heffernan Sep 19 '13 at 12:03
  • 2
    @AndreaBoc: to make it clearer - `TLabel` does not have an `HWND` of its own, so you will not be able to interact with it externally, unless the app manually exposes its own access to it, such as by implementing the `IAccessible` interface (which the VCL does not do by default). – Remy Lebeau Sep 19 '13 at 15:39