Tal
Tal

Reputation: 418

ControlGetHandle in AutoIT

Can anyone tell me what ControlGetHandle() does behind the scenes? What Windows API function does it invoke? How can I see it? (logs/debug mode).

It sometimes succeeds and sometimes fails and I don't understand why. I looked all over the place, including AutoIT .au3 include files, but I couldn't find any information.

Upvotes: 0

Views: 1866

Answers (3)

Tal
Tal

Reputation: 418

So, I discovered this amazing tool called "API Monitor". It shows you API calls made to the OS. You can filter etc. When running AutoIT with "ControlGetHandle" you can see that it actually calls two functions:

  1. EnumWindows
  2. EnumChildWindows

With the relevant parameters to get the handle you wish.

Thanks!

Upvotes: 1

The North Star
The North Star

Reputation: 102

The first thing that comes to mind, the function finds the window with matching caption, lists the controls, finds the control with suitable criteria( class name and text), and returns his HWnd. This is done using the API EnumWindows/GetWindowTextLength/GetWindowText,GetWindowClassName.


Here, I wrote a small example, but it is in Pascal ( Excuse me. later rewritten in 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.

Upvotes: 0

MrAutoIt
MrAutoIt

Reputation: 795

I believe it uses GetDlgCtrlID among other things. If you are having trouble getting it to return a handle sometimes changing the controlID parameter will fix it. Also, make sure you are waiting for the control to load first. If the control exists and you are using the right controlID parameters AutoIt will be able to get a controls handle 99.9999% of the time.

Upvotes: 0

Related Questions