in Tools/UIRecorder/UIXPathLib/UiTreeWalk.cpp [433:528]
HRESULT UiTreeWalk::PathFromRootToTarget(long left, long top)
{
m_pt = { left,top };
m_hWndTarget = WindowFromPoint(m_pt);
BOOL bStartFromRoot = TRUE;
HWND hRoot = GetAncestor(m_hWndTarget, GA_ROOT);
if (hRoot != NULL)
{
WCHAR chClassName[64]{ 0 };
GetClassName(hRoot, chClassName, ARRAYSIZE(chClassName));
if (wcslen(chClassName) > 0)
{
if (wcsncmp(L"Chrome_WidgetWin", chClassName, 16) == 0
|| wcsncmp(L"MozillaWindowClass", chClassName, 18) == 0)
{
// Chrome and Firefox
return PathFromTargetToRoot(left, top);
}
if (wcsncmp(L"Progman", chClassName, 7) == 0
|| wcsncmp(L"IEFrame", chClassName, 7) == 0
|| wcsncmp(L"SysListView32", chClassName, 13) == 0)
{
// desktop icons or IE11
bStartFromRoot = FALSE;
}
}
}
CComPtr<IUIAutomationElement> spRoot;
REQUIRE_SUCCESS_HR(m_spAutomation->GetRootElement(&spRoot.p));
CComPtr<IUIAutomationElement> spTarget;
REQUIRE_SUCCESS_HR(m_spAutomation->ElementFromPoint(m_pt, &spTarget.p));
CComPtr<IUIAutomationElement> spStart;
if (bStartFromRoot == FALSE)
{
// starting from top window is much faster
REQUIRE_SUCCESS_HR(m_spAutomation->ElementFromHandle(hRoot, &spStart.p));
}
else
{
REQUIRE_SUCCESS_HR(spRoot.CopyTo(&spStart.p));
}
// ElementFromPoint may return RECT {0,0,0,0} like UIs on Edge F12
if (SUCCEEDED(spTarget->get_CurrentBoundingRectangle(&s_rectTargetElement)))
{
if (memcmp(&s_rectTargetElement, &rectZero, sizeof(RECT)) == 0)
{
CComPtr<IUIAutomationElement> TempTarget;
if (FAILED(ElementContainingPoint(left, top, spStart, &TempTarget.p)))
{
CComPtr<IUIAutomationElement> spParent;
m_spTreeWalker->GetParentElement(spTarget, &spParent.p);
spTarget.Release();
spTarget = spParent.Detach();
}
else
{
spTarget.Release();
spTarget = TempTarget.Detach();
}
}
}
std::wstring uiPath;
HRESULT hr = GetChildUiNode(left, top, spStart, spTarget, uiPath);
if (hr == S_OK)
{
AppendUiAttributes(left, top, spStart, 0, uiPath);
if (bStartFromRoot == FALSE)
{
AppendUiAttributes(left, top, spRoot, 0, uiPath);
}
swprintf_s(s_chBuffer, BUFFERSIZE, L"%s", uiPath.c_str());
if (SUCCEEDED(spTarget->get_CurrentBoundingRectangle(&s_rectTargetElement)))
{
DrawHighlight();
m_nHighlightTimer = SetTimer(NULL, 0, 500, NULL);
}
}
else
{
PathFromTargetToRoot(left, top);
}
return S_OK;
}