Im using the code above to walk through the descendants of an element, however its not catching everything like i can see using inspect.exe.
inspect-objects
I'm testing in the chrome browser, in this current webpage, its catching just current opened pages, bookmarks, and browser buttons, its missing to catch the page content.
While testing in others windows like a folder for example, it does catch everything correctly, but its taking too much time, in a folder with 120 elements it takes up to 1.4 seconds, i wonder if the code could be improved in any manner?
WCHAR window[250] = L"Ask a question - Microsoft Q&A";
IUIAutomationElement *element = GetTopLevelWindowByName(window);
ListDescendants(element, 2);
IUIAutomationElement* GetTopLevelWindowByName(LPWSTR windowName)
{
if (windowName == NULL)
return NULL;
CComPtr<IUIAutomation> g_pAutomation;
if (SUCCEEDED(CoInitialize(NULL)))
{
if (!SUCCEEDED(g_pAutomation.CoCreateInstance(CLSID_CUIAutomation8))) // or CLSID_CUIAutomation
return NULL;
}
VARIANT varProp;
varProp.vt = VT_BSTR;
varProp.bstrVal = SysAllocString(windowName);
if (varProp.bstrVal == NULL)
return NULL;
IUIAutomationElement* pRoot = NULL;
IUIAutomationElement* pFound = NULL;
IUIAutomationCondition* pCondition = NULL;
// Get the desktop element.
HRESULT hr = g_pAutomation->GetRootElement(&pRoot);
if (FAILED(hr) || pRoot == NULL)
goto cleanup;
// Get a top-level element by name, such as "Program Manager"
hr = g_pAutomation->CreatePropertyCondition(UIA_NamePropertyId, varProp, &pCondition);
if (FAILED(hr))
goto cleanup;
pRoot->FindFirst(TreeScope_Children, pCondition, &pFound);
cleanup:
if (pRoot != NULL)
pRoot->Release();
if (pCondition != NULL)
pCondition->Release();
VariantClear(&varProp);
return pFound;
}
void ListDescendants(IUIAutomationElement* pParent, int indent)
{
static CComPtr<IUIAutomation> g_pAutomation;
if (!g_pAutomation) {
if (SUCCEEDED(CoInitialize(NULL)))
{
if (!SUCCEEDED(g_pAutomation.CoCreateInstance(CLSID_CUIAutomation8))) // or CLSID_CUIAutomation
return;
}
}
if (pParent == NULL)
return;
IUIAutomationTreeWalker* pControlWalker = NULL;
IUIAutomationElement* pNode = NULL;
g_pAutomation->get_ControlViewWalker(&pControlWalker);
if (pControlWalker == NULL)
goto cleanup;
pControlWalker->GetFirstChildElement(pParent, &pNode);
if (pNode == NULL)
goto cleanup;
while (pNode)
{
BSTR sName;
pNode->get_CurrentName(&sName);
UIA_HWND uia_hwnd;
pNode->get_CurrentNativeWindowHandle(&uia_hwnd);
RECT rect;
pNode->get_CurrentBoundingRectangle(&rect);
ListDescendants(pNode, indent + 1);
IUIAutomationElement* pNext;
pControlWalker->GetNextSiblingElement(pNode, &pNext);
pNode->Release();
pNode = pNext;
}
cleanup:
if (pControlWalker != NULL)
pControlWalker->Release();
if (pNode != NULL)
pNode->Release();
return;
}
