有人能告诉我ControlGetHandle()在幕后做了什么吗?它调用了哪些Windows API函数?我怎么能看到它? (日志/调试模式)。
它有时会成功,有时会失败,我不明白为什么。我看了整个地方,包括AutoIT .au3包含文件,但我找不到任何信息。
答案 0 :(得分:1)
所以,我发现了这个名为“API Monitor”的神奇工具。它显示了对OS进行的API调用。您可以过滤等。使用“ControlGetHandle”运行AutoIT时,您可以看到它实际上调用了两个函数:
使用相关参数来获得您想要的句柄。
谢谢!
答案 1 :(得分:0)
首先想到的是,该函数找到具有匹配标题的窗口,列出控件,找到具有合适标准(类名和文本)的控件,并返回其HWnd。这是使用API EnumWindows / GetWindowTextLength / GetWindowText,GetWindowClassName完成的。
在这里,我写了一个小例子,但它是在Pascal中(对不起。后来在AutoIt中重写。;););)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fhw:hwnd;
cls,txt:string;
wind:hwnd;
implementation
{$R *.dfm}
function GetText(wnd:hwnd):string;
var
len:integer;
begin
len:=GetWindowTextLength(wnd)+1;
SetLength(result,len);
SetLength(Result,GetWindowText(wnd,pchar(result),len));
end;
function GetClsName(wnd:hwnd):string;
begin
SetLength(result,5000);
SetLength(result,GetClassName(wnd,pchar(result),5000));
end;
function EnumChildProc(wnd:HWnd; param:Integer):bool;stdcall;
var
wintext,wincls:string;
ccmp,tcmp:boolean;
begin
wintext:=gettext(wnd);
wincls:=getclsname(wnd);
if cls <> '' then
ccmp:=(comparetext(cls,wincls)=0)
else
ccmp:=true;
if txt <> '' then
tcmp:=(comparetext(txt,wintext)=0)
else
tcmp:=true;
result:=not (tcmp and ccmp);
if not result then
wind:=wnd;
end;
procedure GetControlHandle(title:string; wtext:string; clsname:string);
var
hw:hwnd;
begin
wind:=0;
hw:=findwindow(nil,pchar(title));
if hw <> 0 then
begin
cls:=clsname;
txt:=wtext;
EnumChildWindows(hw,@EnumChildProc,integer(pointer(result)));
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
w:hwnd;
begin
getcontrolhandle('New Project','','Button');
w:=wind;
CloseWindow(w);
end;
end.
答案 2 :(得分:0)
我认为它使用GetDlgCtrlID等。如果您在返回句柄时遇到问题,有时更改controlID参数会修复它。此外,请确保您正在等待控件首先加载。如果控件存在并且您正在使用正确的controlID参数,则AutoIt将能够在99.9999%的时间内获得控件句柄。