Example #1
0
HRESULT UiTreeWalk::AppendUiAttributes(long left, long top, IUIAutomationElement* pCurUia, long nPos, std::wstring& wstr)
{
    SAFEARRAY *rid;
    REQUIRE_SUCCESS_HR(pCurUia->GetRuntimeId(&rid));
    LONG lbound;
    REQUIRE_SUCCESS_HR(SafeArrayGetLBound(rid, 1, &lbound));
    LONG ubound;
    REQUIRE_SUCCESS_HR(SafeArrayGetUBound(rid, 1, &ubound));

    CComBSTR bstrRuntimeId;
    LONG runtimeId = 0;
    WCHAR temp[16];
    for (LONG i = lbound; i <= ubound; i++)
    {
        REQUIRE_SUCCESS_HR(SafeArrayGetElement(rid, &i, &runtimeId));
        _ltow_s(runtimeId, temp, 10);
        REQUIRE_SUCCESS_HR(bstrRuntimeId.Append(temp));
        
        if (i < ubound)
        {
            REQUIRE_SUCCESS_HR(bstrRuntimeId.Append(L"."));
        }
    }

    REQUIRE_SUCCESS_HR(SafeArrayDestroy(rid));

    if (bstrRuntimeId == NULL)
    {
        wsprintf(temp, L"%lu", reinterpret_cast<std::uintptr_t>(pCurUia));
        bstrRuntimeId = temp;
    }

    CComPtr<IUIAutomationElement> spUia(pCurUia);
    auto it = cachedAutoElements.find(bstrRuntimeId);
    if (it == cachedAutoElements.end())
    {
        cachedAutoElements.insert(std::make_pair(bstrRuntimeId, spUia));
    }
    else
    {
        it->second = spUia;
    }

    CComBSTR bstrClass;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentClassName(&bstrClass));
    bstrClass = bstrClass == NULL ? L"" : bstrClass;
    std::wstring shortClass(bstrClass, SysStringLen(bstrClass));
    bool bStartWith = XmlEncode(shortClass, MaxNameLength);
    if (bStartWith == true || shortClass.length() >= MaxNameLength)
    {
        shortClass.insert(0, L"starts-with:");
    }

    CComBSTR bstrName;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentName(&bstrName));
    bstrName = bstrName == NULL ? L"" : bstrName;

    std::wstring shortName(bstrName, SysStringLen(bstrName));
    bStartWith = XmlEncode(shortName, MaxNameLength);

    if (bStartWith == true || shortName.length() >= MaxNameLength)
    {
        shortName.insert(0, L"starts-with:");
    }

    CComBSTR bstrCtrlType;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentLocalizedControlType(&bstrCtrlType));
    bstrCtrlType = bstrCtrlType == NULL ? L"" : bstrCtrlType;

    CONTROLTYPEID cid;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentControlType(&cid));

    CComBSTR bstrProgrammaticName;
    if (cid >= UIA_ButtonControlTypeId && UIA_ButtonControlTypeId <= UIA_AppBarControlTypeId)
    {
        REQUIRE_SUCCESS_HR(bstrProgrammaticName.Append(gc_controlTypesTable[cid - UIA_ButtonControlTypeId].pszName));
    }

    // CurrentLocalizedControlType can be empty: Cortana set reminder Time button's parent
    if (bstrProgrammaticName.Length() == 0)
    {
        bstrProgrammaticName = L"Unknown";
    }

    CComBSTR bstrAutoId;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentAutomationId(&bstrAutoId));
    bstrAutoId = bstrAutoId == NULL ? L"" : bstrAutoId;

    std::wstring shortAutoId(bstrAutoId, SysStringLen(bstrAutoId));
    bStartWith = XmlEncode(shortAutoId, MaxNameLength);

    if (bStartWith == true || shortAutoId.length() >= MaxNameLength)
    {
        shortAutoId.insert(0, L"starts-with:");
    }

    RECT rect;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentBoundingRectangle(&rect));

    WCHAR chPos[16];
    if (nPos <= 0)
    {
        wsprintf(chPos, L"");
    }
    else
    {
        wsprintf(chPos, L"%d", nPos + 1); // xpath index starts at 1
    } 

    wsprintf(UiTreeWalk::s_chBuffer,
        c_chNodeFormat,
        bstrProgrammaticName.m_str,
        bstrCtrlType.m_str,
        shortClass.c_str(),
        shortName.c_str(),
        shortAutoId.c_str(),
        rect.left,
        rect.top,
        rect.right - rect.left,
        rect.bottom - rect.top,
        left - rect.left,
        top - rect.top,
        chPos,
        bstrRuntimeId.m_str);

    if (wcslen(UiTreeWalk::s_chBuffer) > 0)
    {
        wstr.append(UiTreeWalk::s_chBuffer);
    }

    return S_OK;
}
Example #2
0
HRESULT UiTreeWalk::AppendUiAttributes(IUIAutomationElement* pCurUia, int nPos, std::wstring& wstr)
{
    CComBSTR bstrClass;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentClassName(&bstrClass));
    bstrClass = bstrClass == NULL ? L"" : bstrClass;

    CComBSTR bstrName;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentName(&bstrName));
    bstrName = bstrName == NULL ? L"" : bstrName;

    std::wstring shortName(bstrName, SysStringLen(bstrName));
    bool bStartWith = XmlEncode(shortName, MaxNameLength);

    if (bStartWith == true || shortName.length() >= MaxNameLength)
    {
        shortName.insert(0, L"starts-with:");
    }

    CComBSTR bstrCtrlType;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentLocalizedControlType(&bstrCtrlType));
    bstrCtrlType = bstrCtrlType == NULL ? L"" : bstrCtrlType;

    CONTROLTYPEID cid;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentControlType(&cid));

    CComBSTR bstrProgrammaticName;
    if (cid >= UIA_ButtonControlTypeId && UIA_ButtonControlTypeId <= UIA_AppBarControlTypeId)
    {
        REQUIRE_SUCCESS_HR(bstrProgrammaticName.Append(gc_controlTypesTable[cid - UIA_ButtonControlTypeId].pszName));
    }

    // CurrentLocalizedControlType can be empty: Cortana set reminder Time button's parent
    if (bstrProgrammaticName.Length() == 0)
    {
        bstrProgrammaticName = L"Unknown";
    }

    CComBSTR bstrAutoId;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentAutomationId(&bstrAutoId));
    bstrAutoId = bstrAutoId == NULL ? L"" : bstrAutoId;

    std::wstring shortAutoId(bstrAutoId, SysStringLen(bstrAutoId));
    bStartWith = XmlEncode(shortAutoId, MaxNameLength);

    if (bStartWith == true || shortAutoId.length() >= MaxNameLength)
    {
        shortAutoId.insert(0, L"starts-with:");
    }

    RECT rect;
    REQUIRE_SUCCESS_HR(pCurUia->get_CurrentBoundingRectangle(&rect));

    WCHAR chPos[16];
    if (nPos <= 0)
    {
        wsprintf(chPos, L"");
    }
    else
    {
        wsprintf(chPos, L"%d", nPos);
    }

    wsprintf(UiTreeWalk::s_chBuffer,
        c_chNodeFormat,
        bstrProgrammaticName.m_str,
        bstrCtrlType.m_str,
        bstrClass.m_str,
        shortName.c_str(),
        shortAutoId.c_str(),
        rect.left,
        rect.top,
        rect.right - rect.left,
        rect.bottom - rect.top,
        chPos);

    if (wcslen(UiTreeWalk::s_chBuffer) > 0)
    {
        wstr.append(UiTreeWalk::s_chBuffer);
    }

    return S_OK;
}