UIAutomation 缺少捕捉一些元素
UIAutomation missing to catch some elements
我正在使用上面的代码遍历 window 的后代,但是,它并没有捕捉到我使用 inspect.exe.
看到的所有内容
目前正在 chrome 浏览器中测试,在当前网页中我正在写这个问题,它只捕获当前打开的页面、书签和浏览器按钮,它缺少捕获页面内容。
例如在文件夹等其他 windows 中进行测试时,它确实能正确捕获所有内容,但它花费的时间太多,在包含 120 个元素的文件夹中它最多需要 1.4 秒,我想知道是否可以通过任何方式改进代码吗?
#include <UIAutomation.h>
#include <UIAutomationCore.h>
#include <UIAutomationClient.h>
#include "Oleacc.h"
#include "atlbase.h"
#pragma comment(lib,"Oleacc.lib")
WCHAR window[250] = L"Ask a Question - Stack Overflow - Google Chrome";
IUIAutomationElement *element = GetTopLevelWindowByName(window);
ListDescendants(element, 2);
IUIAutomationElement* GetTopLevelWindowByName(LPWSTR windowName)
{
if (windowName == NULL)
return NULL;
CComPtr<IUIAutomation> g_pAutomation;
if (SUCCEEDED(CoInitialize(NULL)))
{
if (!SUCCEEDED(g_pAutomation.CoCreateInstance(CLSID_CUIAutomation8))) // or CLSID_CUIAutomation
return NULL;
}
VARIANT varProp;
varProp.vt = VT_BSTR;
varProp.bstrVal = SysAllocString(windowName);
if (varProp.bstrVal == NULL)
return NULL;
IUIAutomationElement* pRoot = NULL;
IUIAutomationElement* pFound = NULL;
IUIAutomationCondition* pCondition = NULL;
// Get the desktop element.
HRESULT hr = g_pAutomation->GetRootElement(&pRoot);
if (FAILED(hr) || pRoot == NULL)
goto cleanup;
// Get a top-level element by name, such as "Program Manager"
hr = g_pAutomation->CreatePropertyCondition(UIA_NamePropertyId, varProp, &pCondition);
if (FAILED(hr))
goto cleanup;
pRoot->FindFirst(TreeScope_Children, pCondition, &pFound);
cleanup:
if (pRoot != NULL)
pRoot->Release();
if (pCondition != NULL)
pCondition->Release();
VariantClear(&varProp);
return pFound;
}
void ListDescendants(IUIAutomationElement* pParent, int indent)
{
static CComPtr<IUIAutomation> g_pAutomation;
if (!g_pAutomation) {
if (SUCCEEDED(CoInitialize(NULL)))
{
if (!SUCCEEDED(g_pAutomation.CoCreateInstance(CLSID_CUIAutomation8))) // or CLSID_CUIAutomation
return;
}
}
if (pParent == NULL)
return;
IUIAutomationTreeWalker* pControlWalker = NULL;
IUIAutomationElement* pNode = NULL;
g_pAutomation->get_ControlViewWalker(&pControlWalker);
if (pControlWalker == NULL)
goto cleanup;
pControlWalker->GetFirstChildElement(pParent, &pNode);
if (pNode == NULL)
goto cleanup;
while (pNode)
{
BSTR sName;
pNode->get_CurrentName(&sName);
UIA_HWND uia_hwnd;
pNode->get_CurrentNativeWindowHandle(&uia_hwnd);
RECT rect;
pNode->get_CurrentBoundingRectangle(&rect);
ListDescendants(pNode, indent + 1);
IUIAutomationElement* pNext;
pControlWalker->GetNextSiblingElement(pNode, &pNext);
pNode->Release();
pNode = pNext;
}
cleanup:
if (pControlWalker != NULL)
pControlWalker->Release();
if (pNode != NULL)
pNode->Release();
return;
}
使用 Chrome 版本 93 和 Windows 10 进行测试:
如果 chrome window 至少部分可见,则 chrome 中的第一个 UIA 子文档是活动选项卡的 html 页,您可以遍历此页面中的 UIA 元素。
如果chrome window不可见,则无法使用UIA访问页面内容。您只能使用 UIA 访问 Chrome 的主要控件,如 here
所述
您可能 运行 Inspect 工具因为小 window 前面部分可见 Chrome window,所以 Inspect 可以看到页面内容。否则检查工具没有什么特别之处。
Chrome 的另一个怪癖是当 Chrome window 处于全屏模式时,UIA 看不到主要控件。相反,UIA 只能看到页面内容(只要 Chrome 没有隐藏在另一个 window 后面)
这似乎是 Chrome 特有的。 Firefox 的行为符合预期。
我正在使用上面的代码遍历 window 的后代,但是,它并没有捕捉到我使用 inspect.exe.
看到的所有内容目前正在 chrome 浏览器中测试,在当前网页中我正在写这个问题,它只捕获当前打开的页面、书签和浏览器按钮,它缺少捕获页面内容。
例如在文件夹等其他 windows 中进行测试时,它确实能正确捕获所有内容,但它花费的时间太多,在包含 120 个元素的文件夹中它最多需要 1.4 秒,我想知道是否可以通过任何方式改进代码吗?
#include <UIAutomation.h>
#include <UIAutomationCore.h>
#include <UIAutomationClient.h>
#include "Oleacc.h"
#include "atlbase.h"
#pragma comment(lib,"Oleacc.lib")
WCHAR window[250] = L"Ask a Question - Stack Overflow - Google Chrome";
IUIAutomationElement *element = GetTopLevelWindowByName(window);
ListDescendants(element, 2);
IUIAutomationElement* GetTopLevelWindowByName(LPWSTR windowName)
{
if (windowName == NULL)
return NULL;
CComPtr<IUIAutomation> g_pAutomation;
if (SUCCEEDED(CoInitialize(NULL)))
{
if (!SUCCEEDED(g_pAutomation.CoCreateInstance(CLSID_CUIAutomation8))) // or CLSID_CUIAutomation
return NULL;
}
VARIANT varProp;
varProp.vt = VT_BSTR;
varProp.bstrVal = SysAllocString(windowName);
if (varProp.bstrVal == NULL)
return NULL;
IUIAutomationElement* pRoot = NULL;
IUIAutomationElement* pFound = NULL;
IUIAutomationCondition* pCondition = NULL;
// Get the desktop element.
HRESULT hr = g_pAutomation->GetRootElement(&pRoot);
if (FAILED(hr) || pRoot == NULL)
goto cleanup;
// Get a top-level element by name, such as "Program Manager"
hr = g_pAutomation->CreatePropertyCondition(UIA_NamePropertyId, varProp, &pCondition);
if (FAILED(hr))
goto cleanup;
pRoot->FindFirst(TreeScope_Children, pCondition, &pFound);
cleanup:
if (pRoot != NULL)
pRoot->Release();
if (pCondition != NULL)
pCondition->Release();
VariantClear(&varProp);
return pFound;
}
void ListDescendants(IUIAutomationElement* pParent, int indent)
{
static CComPtr<IUIAutomation> g_pAutomation;
if (!g_pAutomation) {
if (SUCCEEDED(CoInitialize(NULL)))
{
if (!SUCCEEDED(g_pAutomation.CoCreateInstance(CLSID_CUIAutomation8))) // or CLSID_CUIAutomation
return;
}
}
if (pParent == NULL)
return;
IUIAutomationTreeWalker* pControlWalker = NULL;
IUIAutomationElement* pNode = NULL;
g_pAutomation->get_ControlViewWalker(&pControlWalker);
if (pControlWalker == NULL)
goto cleanup;
pControlWalker->GetFirstChildElement(pParent, &pNode);
if (pNode == NULL)
goto cleanup;
while (pNode)
{
BSTR sName;
pNode->get_CurrentName(&sName);
UIA_HWND uia_hwnd;
pNode->get_CurrentNativeWindowHandle(&uia_hwnd);
RECT rect;
pNode->get_CurrentBoundingRectangle(&rect);
ListDescendants(pNode, indent + 1);
IUIAutomationElement* pNext;
pControlWalker->GetNextSiblingElement(pNode, &pNext);
pNode->Release();
pNode = pNext;
}
cleanup:
if (pControlWalker != NULL)
pControlWalker->Release();
if (pNode != NULL)
pNode->Release();
return;
}
使用 Chrome 版本 93 和 Windows 10 进行测试:
如果 chrome window 至少部分可见,则 chrome 中的第一个 UIA 子文档是活动选项卡的 html 页,您可以遍历此页面中的 UIA 元素。
如果chrome window不可见,则无法使用UIA访问页面内容。您只能使用 UIA 访问 Chrome 的主要控件,如 here
所述您可能 运行 Inspect 工具因为小 window 前面部分可见 Chrome window,所以 Inspect 可以看到页面内容。否则检查工具没有什么特别之处。
Chrome 的另一个怪癖是当 Chrome window 处于全屏模式时,UIA 看不到主要控件。相反,UIA 只能看到页面内容(只要 Chrome 没有隐藏在另一个 window 后面)
这似乎是 Chrome 特有的。 Firefox 的行为符合预期。