如何通过 UIA_AutomationIdPropertyId 找到 UI 自动化元素

问题描述 投票:0回答:1

我想获得一个只能由 UIA_AutomationIdPropertyId 识别的组元素。

我从 Inspect.exe 得到了 AutomationId

所以我写了以下功能。

IUIAutomationElement* FindBy_UIA_AID(std::wstring UID)
{
    IUIAutomationElement* pElement = nullptr;
    IUIAutomationCondition* condition = nullptr;
    
    VARIANT var{};
    var.bstrVal = SysAllocStringLen(UID.c_str(), UID.size());
    var.vt = VT_BSTR;

    hr = pAutomation->CreatePropertyCondition(UIA_AutomationIdPropertyId, var, &condition);
    if (FAILED(hr))
    {
        std::cout << "Error Creating Condition\n";
        return nullptr;
    }

    hr = MainElement->FindFirst(TreeScope_Subtree, condition, &pElement);
    if (FAILED(hr))
    {
        std::cout << "Error Finding First Occurence\n";
        condition->Release();
        return nullptr;
    }

    condition->Release();
    SysFreeString(var.bstrVal);
    return pElement;
}

但这总是返回 nullptr(但没有错误)。所以我查看了 Inspect.exe 以检查该组是否是我的 MainElement 的后代,它是。我还写了另一个函数,在此之前 absolutley 工作正常。

该函数的作用完全相同,只是通过 UIA_LegacyIAccessibleNamePropertyId 进行搜索。 这行得通,找到的元素与我用 .

寻找的元素在同一树范围内
IUIAutomationElement* FindBy_UIA_NPI(std::wstring name)
{
    IUIAutomationElement* pElement = nullptr;
    IUIAutomationCondition* condition = nullptr;

    VARIANT var{};
    var.bstrVal = SysAllocStringLen(name.c_str(), name.size());
    var.vt = VT_BSTR;

    hr = pAutomation->CreatePropertyCondition(UIA_LegacyIAccessibleNamePropertyId, var, &condition);
    if (FAILED(hr))
    {
        std::cout << "Error Creating Condition\n";
        return nullptr;
    }

    hr = MainElement->FindFirst(TreeScope_Subtree, condition, &pElement);
    if (FAILED(hr))
    {
        std::cout << "Error Finding First Occurence\n";
        condition->Release();
        return nullptr;
    }

    SysFreeString(var.bstrVal);
    condition->Release();

    return pElement;
}

所以现在我想知道问题出在哪里,或者如何以另一种方式通过 UIA_AutomationIdPropertyId 获取元素。

注意。前面两个函数都是成员函数,类有以下有效成员

HRESULT hr{};
HWND hwnd{};
IUIAutomation* pAutomation{};
IUIAutomationElement* MainElement{};

编辑:在手动遍历 MainElement 的每个后代后,我发现许多元素没有 AutomationID,即使在 Inspect.exe 中它们有,这很奇怪。也许有人知道这是为什么以及如何解决这个

c++ windows automation ui-automation microsoft-ui-automation
1个回答
0
投票

经过一番调查,我发现问题出在Inspect.exe工具本身。我不小心将它留在

Raw View
模式,这导致它显示
Raw Tree
而不是 UI Automation API 使用的
Actual Tree

我正在寻找的元素不是

Control Element
所以没有必要尝试使用
FindAll
进行搜索,因为
IUIAutomationElement::IsControlElement
属性设置为
FALSE
.

要解决此问题,可以将模式更改为

Control View
或使用“IUIAutomationTreeWalker”。

这个也值得一看

© www.soinside.com 2019 - 2024. All rights reserved.