c++ 如何使用UiAutomation获取LegacyIAccessible数据?

kyxcudwk  于 2023-04-13  发布在  其他
关注(0)|答案(2)|浏览(1710)

我正在尝试获取下图中标记的LegacyIAccessible值:

到目前为止,我已经能够阅读这些:

#include <UIAutomation.h> // UIAutomation includes.
#include <UIAutomationCore.h>
#include <UIAutomationClient.h>
#include "Oleacc.h"
#include "atlbase.h"
#pragma comment(lib,"Oleacc.lib")

LPCWSTR Acc(HWND hwnd) {

    CComPtr<IUIAutomation> pUIAutomation;
    CoInitialize(NULL);
    HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pUIAutomation);
    if (SUCCEEDED(hr))
    {
        IUIAutomationElement* pRoot = NULL;
        hr = pUIAutomation->ElementFromHandle(hwnd, &pRoot);
        if (SUCCEEDED(hr))
        {
            IUIAutomationElementArray* pElementArray = nullptr;
            IUIAutomationCondition* pCondition;
            hr = pUIAutomation->CreateTrueCondition(&pCondition);
            IUIAutomationElementArray* pEA;
            IUIAutomationCacheRequest* pCacheRequest;
            hr = pUIAutomation->CreateCacheRequest(&pCacheRequest);
            pCacheRequest->AddProperty(UIA_NamePropertyId);
            pCacheRequest->AddProperty(UIA_AutomationIdPropertyId);
            pCacheRequest->AddProperty(UIA_LocalizedControlTypePropertyId);
            //pCacheRequest->put_TreeScope((TreeScope)(TreeScope_Element | TreeScope_Descendants));
            hr = pRoot->FindAllBuildCache(TreeScope_Descendants, pCondition, pCacheRequest, &pEA);
            if (SUCCEEDED(hr))
            {
                int nNbItems = 0;
                hr = pEA->get_Length(&nNbItems);
                for (int nItem = 0; nItem <= nNbItems - 1; nItem++)
                {
                    IUIAutomationElement* pElement = nullptr;
                    hr = pEA->GetElement(nItem, &pElement);

                    BSTR name;
                    pElement->get_CurrentName(&name);

                    UIA_HWND uia_hwnd = nullptr;
                    pElement->get_CurrentNativeWindowHandle(&uia_hwnd);

                    BSTR classname = nullptr;
                    pElement->get_CurrentClassName(&classname);
                    
                    RECT rect;
                    pElement->get_CurrentBoundingRectangle(&rect);
        
                    pElement->Release();
                }
            }

            pCacheRequest->Release();
            pCondition->Release();
            pRoot->Release();
        }

        
        //pUIAutomation->Release();   // <- needed?
    }

    CoUninitialize();
    return (L"SUCCEEDED");
}

当我尝试呼叫:

DWORD CurrentState;
    pElement->get_CurrentState(&CurrentState);

我得到这个错误:class "IUIAutomationElement" has no member "get_CurrentState" .
我想我应该使用IUIAutomationLegacyIAccessiblePattern,但我不知道如何正确地使用它重写函数。
另外,函数withwithout 'cache'之间有什么区别?

rfbsl7qr

rfbsl7qr1#

一个GetCurrentPatternAs的例子。不涉及缓存。

#include <Windows.h>
#include <UIAutomation.h>
#include <wchar.h>

int Element(IUIAutomation* automation)
{
    // Get the element under the cursor
// Use GetPhysicalCursorPos to interact properly with
// High DPI
    POINT pt;
    GetPhysicalCursorPos(&pt);

    IUIAutomationElement* pAtMouse;
    HRESULT hr = automation->ElementFromPoint(pt, &pAtMouse);
    if (FAILED(hr))
        return hr;

    // Get the element's name and print it
    BSTR name;
    hr = pAtMouse->get_CurrentName(&name);
    if (SUCCEEDED(hr))
    {
        wprintf(L"Element's Name: %s \n", name);
        SysFreeString(name);

        //IUIAutomationValuePattern* pattern;
        //pAtMouse->GetCurrentPatternAs(UIA_ValuePatternId, IID_IUIAutomationValuePattern,(void**)&pattern);
        IUIAutomationLegacyIAccessiblePattern* pattern;
        
        //pAtMouse->GetCurrentPatternAs(UIA_LegacyIAccessiblePatternId, IID_IUIAutomationLegacyIAccessiblePattern,(void**)&pattern);
        pAtMouse->GetCurrentPatternAs(UIA_LegacyIAccessiblePatternId, IID_PPV_ARGS(&pattern));
        //TODO
        BSTR url = nullptr;
        pattern->get_CurrentValue(&url);
        DWORD state = 0;
        pattern->get_CurrentState(&state);
        BSTR elename = nullptr;
        pattern->get_CurrentName(&elename);
        DWORD role = 0;
        pattern->get_CurrentRole(&role);
        //wprintf(L"Element's ValuePattern: %s \n", url);
        SysFreeString(url);
        SysFreeString(elename);
    }

    // Get the element's Control Type (in the current languange)
    // and print it
    BSTR controlType;
    hr = pAtMouse->get_CurrentLocalizedControlType(&controlType);
    if (SUCCEEDED(hr))
    {
        wprintf(L"Element's Control Type: %s \n", controlType);
        SysFreeString(controlType);
    }

    // Clean up our COM pointers
    pAtMouse->Release();
    return hr;
}

int main(int argc, TCHAR* argv[])
{
    // Initialize COM and create the main Automation object
    IUIAutomation* g_pAutomation;
    CoInitialize(NULL);
    HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL,
        CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation),
        (void**)&g_pAutomation);
    if (FAILED(hr))
        return (hr);

    bool quit = false;
    while (!quit)
    {
        SHORT leftControlMod = GetAsyncKeyState(VK_LCONTROL);
        if (leftControlMod != 0)
        {
            Element(g_pAutomation);
        }
        quit = GetAsyncKeyState(VK_ESCAPE);
    }

    g_pAutomation->Release();
    CoUninitialize();
    return 0;
}

blmhpbnm

blmhpbnm2#

在Python中,可以通过以下方式使用uiautomation.py库找到控件后找到LegacyIAccessible的名称和值:
假设你已经找到了控件elem_control

elem_control.GetLegacyIAccessiblePattern().Value  # to get the legacy value

elem_control.GetLegacyIAccessiblePattern().Name   # to get the legacy name

ValueNameLegacyIAccessiblePattern类的属性。

相关问题