MFC or WIN32 UI Automation Client Sample?

一笑奈何 提交于 2020-08-06 04:31:18

问题


I have been looking for a sample of using UI Automation in MFC (or Win32) as a client to scroll another applications window. But I can't find any samples?

Does anyone know of one or can provide one?


回答1:


The following is a Win32 C++ example of scrolling vertically on a notepad window: testWindow.txt - Notepad.

Main steps:

  1. Find the main window handle of target application using FindWindow.

    FindWindow(L"Notepad", L"testWindow.txt - Notepad");

  2. Get IUIAutomationElement object from above found window handle.

    pClientUIA->ElementFromHandle(targetWindow, &pRootElement);

  3. Find the handle of the window which containing the scrollbar using UIA_ScrollBarControlTypeId and NormalizeElement.

  4. Send WM_VSCROLL message to the window containing the scrollbar.

    PostMessage(foundHwnd, WM_VSCROLL, SB_LINEUP, 0);

This is the complete code you can refer to:

#include <windows.h>
#include <uiautomation.h>

IUIAutomation *pClientUIA;
IUIAutomationElement *pRootElement;

HWND FindScrollbarContainerWindow(const long controlType)
{
    HRESULT hr;
    BSTR name;
    IUIAutomationCondition *pCondition;
    VARIANT varProp;
    varProp.vt = VT_I4;
    varProp.uintVal = controlType;
    hr = pClientUIA->CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, &pCondition);
    if (S_OK != hr)
    {
        printf("CreatePropertyCondition error: %d\n", hr);
    }

    IUIAutomationElementArray *pElementFound;
    hr = pRootElement->FindAll(TreeScope_Subtree, pCondition, &pElementFound);
    if (S_OK != hr)
    {
        printf("CreatePropertyCondition error: %d\n", hr);
    }
    int eleCount;
    pElementFound->get_Length(&eleCount);
    if (eleCount == 0)
        return NULL;

    for (int i = 0; i <= eleCount; i++)
    {
        IUIAutomationElement *pElement;
        hr = pElementFound->GetElement(i, &pElement);
        if (S_OK != hr)
        {
            printf("CreatePropertyCondition error: %d\n", hr);
        }
        hr = pElement->get_CurrentName(&name);
        if (S_OK != hr)
        {
            printf("CreatePropertyCondition error: %d\n", hr);
        }
        wprintf(L"Control Name: %s\n", name);

        hr = pElement->get_CurrentClassName(&name);
        if (S_OK != hr)
        {
            printf("CreatePropertyCondition error: %d\n", hr);
        }
        wprintf(L"Class Name: %s\n", name);

        IUIAutomationTreeWalker* pContentWalker = NULL;

        hr = pClientUIA->get_ContentViewWalker(&pContentWalker);
        if (pContentWalker == NULL)
            return NULL;

        // Get ancestor element nearest to the scrollbar UI Automation element in the tree view
        IUIAutomationElement *ncestorElement;
        hr = pContentWalker->NormalizeElement(pElement, &ncestorElement);

        hr = ncestorElement->get_CurrentName(&name);
        wprintf(name);

        // Get window handle of ancestor element
        UIA_HWND controlContainerHwnd = NULL;
        hr = ncestorElement->get_CurrentNativeWindowHandle(&controlContainerHwnd);
        printf("");

        if (controlContainerHwnd)
        {
            return (HWND)controlContainerHwnd;
        }
    }

    return NULL;
}

int main()
{
    // Find target window
    HWND targetWindow = FindWindow(L"Notepad", L"testWindow.txt - Notepad");
    if (NULL == targetWindow)
    {
        printf("FindWindow fails with error: %d\n", GetLastError());
        return FALSE;
    }

    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (S_OK != hr)
    {
        printf("CoInitializeEx error: %d\n", hr);
        return 1;
    }

    hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER, IID_IUIAutomation, reinterpret_cast<void**>(&pClientUIA));
    if (S_OK != hr)
    {
        printf("CoCreateInstance error: %d\n", hr);
        return 1;
    }

    hr = pClientUIA->ElementFromHandle(targetWindow, &pRootElement);
    if (S_OK != hr)
    {
        printf("ElementFromHandle error: %d\n", hr);
        return 1;
    }

    // Find scroll bar and its containing window
    HWND foundHwnd = FindScrollbarContainerWindow(UIA_ScrollBarControlTypeId);
    if (NULL == foundHwnd)
        return 1;

    // Vertical scroll bar
    // Line up - Like click top arrow button to scroll up one line
    PostMessage(foundHwnd, WM_VSCROLL, SB_LINEUP, 0);
    Sleep(1000);

    // Line down
    PostMessage(foundHwnd, WM_VSCROLL, SB_LINEDOWN, 0);
    Sleep(1000);

    // Page up
    PostMessage(foundHwnd, WM_VSCROLL, SB_PAGEUP, 0);
    Sleep(1000);

    // Page down
    PostMessage(foundHwnd, WM_VSCROLL, SB_LINEDOWN, 0);
    Sleep(1000);
}

--------------------------------------------------------------

UPDATE:

Another method is using IUIAutomationScrollPattern::Scroll(). More direct and simple. Similar thread.



来源:https://stackoverflow.com/questions/62143582/mfc-or-win32-ui-automation-client-sample

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!