【问题标题】:ControlGetHandle in AutoITAutoIT 中的 ControlGetHandle
【发布时间】:2015-11-09 14:11:27
【问题描述】:

谁能告诉我 ControlGetHandle() 在幕后做了什么?它调用什么 Windows API 函数?我怎么能看到它? (日志/调试模式)。

它有时会成功,有时会失败,我不明白为什么。我到处查看,包括 AutoIT .au3 包含文件,但找不到任何信息。

【问题讨论】:

    标签: autoit


    【解决方案1】:

    所以,我发现了这个名为“API Monitor”的神奇工具。它显示了对操作系统的 API 调用。您可以过滤等。当使用“ControlGetHandle”运行 AutoIT 时,您可以看到它实际上调用了两个函数:

    1. 枚举窗口
    2. EnumChildWindows

    用相关参数得到你想要的句柄。

    谢谢!

    【讨论】:

      【解决方案2】:

      我相信它使用GetDlgCtrlID 等等。如果您无法让它返回一个句柄,有时更改 controlID 参数将修复它。另外,请确保您正在等待控件首先加载。如果控件存在并且您使用正确的 controlID 参数 AutoIt 将能够在 99.9999% 的时间内获得控件句柄。

      【讨论】:

      • 在大多数情况下,它是非常不可靠的。
      • 这是基于什么?多年来,我已经构建了数百个使用 ControlGetHandle() 自动化程序的脚本,而且我很难想到任何时候它不起作用。
      【解决方案3】:

      首先想到的是,该函数找到具有匹配标题的窗口,列出控件,找到具有合适条件(类名和文本)的控件,并返回他的 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.
      

      【讨论】:

        猜你喜欢
        • 2014-07-06
        • 2015-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-11
        • 1970-01-01
        • 2018-04-15
        • 1970-01-01
        相关资源
        最近更新 更多