Home > Software engineering >  UIAutomation missing to catch some elements
UIAutomation missing to catch some elements

Time:09-18

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;
 }

CodePudding user response:

Testing with Chrome version 93 and Windows 10:

If chrome window is at least partially visible, the first UIA child document in chrome is html page of the active tab, and you can walk the UIA elements in this page.

If chrome window is not visible, you cannot access the page content with UIA. You can only use UIA to access the main controls for Chrome, as explained here

You probably run the Inspect tool as small window in front of a partially visible Chrome window, so Inspect can see the page content. Otherwise there is nothing special about the Inspect tool.

Another quirk with Chrome is that when the Chrome window is in full-screen mode, the main controls are not seen by UIA. Instead only the page content is seen by UIA (as long as Chrome is not hidden behind another window)

This seems to be specific to Chrome. Firefox behaves as expected.

  • Related