Search code examples
c++ui-automationmicrosoft-ui-automation

How do you get the NamePropertyId of a UIAutomationElement by hovering the cursor?


I am trying to build my own screen reader using UIAutomation. I want my program to return the NameProperty of the element that is pointed by my cursor

This is what I have done so far; this is just sample code anyway:

#include <iostream>
#include <windows.h>
#include <UIAutomation.h>

const int MAX_WND_TEXT = 60;

IUIAutomation *automation = NULL;

BOOL InitializeUIAutomation(IUIAutomation **pAutomation)
{
    CoInitialize(NULL);
    HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL,
        CLSCTX_INPROC_SERVER,
        __uuidof(IUIAutomation), (void**)pAutomation);
    return (SUCCEEDED(hr));
}

int main()
{
    POINT p;

    IUIAutomationElement *elem;
    wchar_t wndName[MAX_WND_TEXT];
    BOOL stat = InitializeUIAutomation(&automation);
    while (true)
    {
        if (stat)
        {
            GetCursorPos(&p);
            HRESULT hr = automation->ElementFromPoint(p, &elem);
            if (SUCCEEDED(hr))
            {
                HRESULT hr = elem->GetCurrentPropertyValue(UIA_NamePropertyId,
                    (VARIANT*)wndName);
                if (SUCCEEDED(hr))
                    std::cout << wndName << std::endl;
                else
                    wndName[0] = '\0';
            }
            else
                std::cout << "No element selected." << std::endl;

            Sleep(100);
            elem->Release();
        }
    }
    automation->Release();
    CoUninitialize();
    return 0;
}

Now the problem is I can't make it to print the values I wanted. The program just output a specific hex number. And also I'm still a beginner in UIAutomation so I am still lost.

Can you help me or give me tips how to solve my problem?


Solution

  • Solved my problem using this code.

    #include <iostream>
    #include <string>
    #include <Windows.h>
    #include <UIAutomation.h>
    
    BOOL InitializeUIAutomation(IUIAutomation **automation)
    {
        CoInitialize(NULL);
        HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL,
            CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation),
            (void**)automation);
        return (SUCCEEDED(hr));
    }
    
    int main()
    {
        IUIAutomation *automation = NULL;
        IUIAutomationElement *elem = NULL;
        BOOL stat = InitializeUIAutomation(&automation);
        POINT mousePt;
        BSTR elemName = NULL;
        if (stat)
        {
            while(true)
            {
                GetCursorPos(&mousePt);
                HRESULT hr = automation->ElementFromPoint(mousePt, &elem);
                if (SUCCEEDED(hr) && elem != NULL)
                {
                    elem->get_CurrentName(&elemName);
                    std::wstring ws(elemName, SysStringLen(elemName));
                    std::wcout << ws << std::endl;
                }
                SysFreeString(elemName);
                elem->Release();
                Sleep(200);
            }
        }
        automation->Release();
        CoUninitialize();
    
        return 0;
    }
    

    The hex numbers printed was the BSTR header after all. Solve my problem by converting BSTR to wstring.