Delphi通过EnumWindows、Enumchildwindows或Spy+检查TGroupBox内的外部TLabel+;

Delphi通过EnumWindows、Enumchildwindows或Spy+检查TGroupBox内的外部TLabel+;,delphi,delphi-xe2,spy++,tlabel,tcombobox,Delphi,Delphi Xe2,Spy++,Tlabel,Tcombobox,我正在用Delphi XE2开发一个应用程序,它通过函数EnumWindows和EnumChildWindows检查同样用Delphi编写的正在运行的应用程序的窗口 这是主代码(改编自一个示例:) 函数EnumChildWindowsProc(Wnd:HWnd;Form:TForm1):Bool;出口; {$ifdef Win32}stdcall;{$endif} 变量 缓冲区:字符的数组[0..99]; 开始 GetWindowText(Wnd,缓冲区,100); 如果StrPas(Buffe

我正在用Delphi XE2开发一个应用程序,它通过函数EnumWindows和EnumChildWindows检查同样用Delphi编写的正在运行的应用程序的窗口

这是主代码(改编自一个示例:)

函数EnumChildWindowsProc(Wnd:HWnd;Form:TForm1):Bool;出口; {$ifdef Win32}stdcall;{$endif} 变量 缓冲区:字符的数组[0..99]; 开始 GetWindowText(Wnd,缓冲区,100); 如果StrPas(Buffer)='',则Buffer:='空'; 新的(AWindows); 用AWindows^do 开始 WindowHandle:=Wnd; WindowText:=StrPas(缓冲区); 结束; CNode:=Form1.TreeView1.Items.AddChildObject(PNode, AWindows^.WindowText+':'+ IntToHex(AWindows^.WindowHandle,8),AWindows); 如果GetWindow(Wnd,GW_CHILD)=0,则 开始 PNode:=CNode; Enumchildwindows(Wnd,@EnumChildWindowsProc,0); 结束; 结果:=真; 结束; 函数EnumWindowsProc(Wnd:HWnd;Form:TForm1):Bool; 出口;{$ifdef Win32}stdcall;{$endif} 变量 缓冲区:字符的数组[0..99]; 开始 GetWindowText(Wnd,缓冲区,100); 如果StrPas(Buffer)='',则Buffer:='空'; 新的(AWindows); 用AWindows^do 开始 WindowHandle:=Wnd; WindowText:=StrPas(缓冲区); 结束;
如果Pos(Form1.edAppToFind.Text,AWindows^.WindowText)>0,则/这不是组框控件的问题。问题是
TLabel
控件未打开窗口。没有与之关联的窗口句柄,因此Spy++、
EnumChildWindows
等无法找到它。

这不是组框控件的问题。问题是
TLabel
控件未打开窗口。没有与之关联的窗口句柄,因此Spy++、
EnumChildWindows
等无法找到它。

事实上,TLabel没有枚举,问题不是Tmbobox,而是TLabel。。。有办法找到窗户里面的标签吗?这正是我要告诉你们的。由于
TLabel
没有窗口句柄,因此依赖于
EnumChildWindows
(如AutoIT和Spy++)的外部工具无法找到它。公开UI以实现自动化的标准方法是使用自动化界面。当前的标准是UIAutomation。我必须检查第三方应用程序,因此如果应用程序包含简单的TLabel,则无法使用EnumWindow或EnumChildwindow读取其中的文本,对吗?还有其他方法可以读取它吗?除非应用程序公开一个自动化接口,否则您将陷入困境。和卖主谈谈。我想我已经回答了你问的问题。@AndreaBoc:为了更清楚地说明-
TLabel
没有自己的
HWND
,因此你将无法与它进行外部交互,除非应用程序手动公开自己对它的访问,例如通过实现
IAccessible
接口(VCL默认情况下不会这样做)。事实上,TLabel没有枚举,问题不是TComboBox而是TLabel…有办法在窗口内找到标签?这正是我要告诉你的。由于
TLabel
没有窗口句柄,依赖于
EnumChildWindows
的外部工具(如AutoIT和Spy++)找不到它。为实现自动化而公开UI的标准方法是使用自动化接口。当前的标准是UIAutomation。我必须检查第三方应用程序,因此如果应用程序包含简单的TLabel,则无法使用EnumWindow或EnumChildwindow读取其上的文本,对吗?有其他读取方法吗?除非应用程序Inogation公开了一个自动化界面,您被卡住了。请与供应商联系。我想我已经回答了您提出的问题。@AndreaBoc:为了更清楚地说明-
TLabel
没有自己的
HWND
,因此您将无法与它进行外部交互,除非该应用程序手动公开自己对它的访问,例如通过实现
IAccessible
接口(VCL默认情况下不会这样做)。
TLabel
不是窗口。
TLabel
不是窗口。
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;