I want to get a group element which is only identifyable by the UIA_AutomationIdPropertyId.
I got the AutomationId from Inspect.exe
So i wrote following function.
IUIAutomationElement* FindBy_UIA_AID(std::wstring UID)
{
IUIAutomationElement* pElement = nullptr;
IUIAutomationCondition* condition = nullptr;
VARIANT var{};
var.bstrVal = SysAllocStringLen(UID.c_str(), UID.size());
var.vt = VT_BSTR;
hr = pAutomation->CreatePropertyCondition(UIA_AutomationIdPropertyId, var, &condition);
if (FAILED(hr))
{
std::cout << "Error Creating Condition\n";
return nullptr;
}
hr = MainElement->FindFirst(TreeScope_Subtree, condition, &pElement);
if (FAILED(hr))
{
std::cout << "Error Finding First Occurence\n";
condition->Release();
return nullptr;
}
condition->Release();
SysFreeString(var.bstrVal);
return pElement;
}
but this always return nullptr (but without error). So i looked at Inspect.exe to check if the group is a descendants of my MainElement, which it is. I also wrote another function before which absolutley works fine.
The function does the exact same just searching by UIA_LegacyIAccessibleNamePropertyId. This works and the element found is in same treescope as the element im looking for with .
IUIAutomationElement* FindBy_UIA_NPI(std::wstring name)
{
IUIAutomationElement* pElement = nullptr;
IUIAutomationCondition* condition = nullptr;
VARIANT var{};
var.bstrVal = SysAllocStringLen(name.c_str(), name.size());
var.vt = VT_BSTR;
hr = pAutomation->CreatePropertyCondition(UIA_LegacyIAccessibleNamePropertyId, var, &condition);
if (FAILED(hr))
{
std::cout << "Error Creating Condition\n";
return nullptr;
}
hr = MainElement->FindFirst(TreeScope_Subtree, condition, &pElement);
if (FAILED(hr))
{
std::cout << "Error Finding First Occurence\n";
condition->Release();
return nullptr;
}
SysFreeString(var.bstrVal);
condition->Release();
return pElement;
}
So now i wonder where the issue could be or how to get an element by UIA_AutomationIdPropertyId in another way.
Note. Both of the previous functions are member functions and the class has following valid members
HRESULT hr{};
HWND hwnd{};
IUIAutomation* pAutomation{};
IUIAutomationElement* MainElement{};
EDIT: After manually looping through every descendant of MainElement I found out that many elements have no AutomationID even though in Inspect.exe they do, which is quite weird. Maybe someone knows why this is and how to fix this
After some investigation, I discovered that the issue was with the Inspect.exe tool itself. I had accidentally left it in Raw View
mode, which was causing it to show the Raw Tree
instead of the Actual Tree
which is used by the UI Automation API.
The element i was looking for was not a Control Element
so there is no point in trying to search with FindAll
as the IUIAutomationElement::IsControlElement
property is set to FALSE
.
To fix the issue, one can either change the mode to Control View
or use "IUIAutomationTreeWalker".
This is also worth taking a look at.