我正在尝试使用UIAutomation访问/控制Chrome浏览器(根据其他人使用的方法使用该方法 - 例如获取当前网址)。
为了练习的目的,我试图在Delphi中复制这个问题 - Retrieve current URL from C# windows forms application。我已经导入TLB了。但是,我对ElementFromHandle的调用永远不会找到一个元素。
ElementFromHandle方法的签名是:
function ElementFromHandle(hwnd: Pointer; out element: IUIAutomationElement): HResult; stdcall;
我的测试很简单:
procedure TForm3.Button1Click(Sender: TObject);
var
UIAuto: IUIAutomation;
element: IUIAutomationElement;
value: WideString;
h: PInteger;
begin
new(h);
h^ := $1094E;
SetForegroundWindow(h^);
ShowWindow(h^, SW_SHOW);
UIAuto := CoCUIAutomation.Create;
UIAuto.ElementFromHandle(h, element);
if Assigned(element) then
begin
element.Get_CurrentName(value);
showmessage('found -' + value);
end
else
showMessage('not found');
end;
调用SetForegroundWindow和ShowWindow只是在需要焦点的情况下(但我怀疑它会有所作为并且没有)。我可以确认传递的句柄($ 1094E)是"正确"尽管Spy ++显示了Chrome标签我尝试访问的价值。 Chrome中的有效标签始终会报告Handle。
我的实施是否正确?使用UIAutomation还有比我上面实现的更多吗?我以前从未探索过它。
由于
修改
我发现如果我使用ElementFromPoint并传入一个(硬编码)值,我知道我的Tab位于X,Y的位置 - 它确实有效。即:
UIAuto := CoCUIAutomation.Create;
p.x := 2916;
p.y := 129;
UIAuto.ElementFromPoint(p, element);
if Assigned(element) then
如果放在上面的OnClick事件中,上面的片段确实会返回一个元素实例和我期待的那个(这是一个奖励)。那么也许我在ElementFromHandle中为Hwnd传递了一个不正确的值?即,我使用" top"找到我的MS Spy ++的Chrome级别句柄:
它直接位于Spy ++中的(桌面)。
答案 0 :(得分:1)
您的错误在于将窗口句柄传递给ElementFromHandle
。您打算通过HWND
。而是传递HWND
的地址。
该功能应该是:
function ElementFromHandle(hwnd: HWND;
out element: IUIAutomationElement): HResult; stdcall;
您应该删除对New
的调用,而是执行:
var
window: HWND;
....
window := HWND($1094E);
然后调用这个函数:
if Succeeded(UIAuto.ElementFromHandle(window, element)) then
....
也许你最大的根本问题是完全没有错误检查。我认为您需要调整您的思维方式,以便意识到这些API调用不会引发异常。他们通过返回值报告失败。您必须检查每个API调用是否失败。
执行此操作的一种常见方法是,在调用HRESULT
失败的情况下,将OleCheck
值转换为异常。例如:
var
UIAuto: IUIAutomation;
element: IUIAutomationElement;
value: WideString;
window: HWND;
....
window := HWND($1094E);
SetForegroundWindow(window);
ShowWindow(window, SW_SHOW);
UIAuto := CoCUIAutomation.Create;
OleCheck(UIAuto.ElementFromHandle(window, element));
OleCheck(element.Get_CurrentName(value));
ShowMessage('found -' + value);