I'm using the code above to walk through the descendants of a window, however, it's not catching everything like I can see using inspect.exe.
Currently testing in the chrome browser, in this current webpage I'm writing this question, it's catching just current opened pages, bookmarks, and browser buttons, it's missing to catch the page content.
While testing in other windows like a folder, for example, it does catch everything correctly, but it's 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?
#include <UIAutomation.h>
#include <UIAutomationCore.h>
#include <UIAutomationClient.h>
#include "Oleacc.h"
#include "atlbase.h"
#pragma comment(lib,"Oleacc.lib")
WCHAR window[250] = L"Ask a Question - Stack Overflow - Google Chrome";
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;
}