in Tools/UIRecorder/UIXPathLib/UiTreeWalk.cpp [351:431]
HRESULT UiTreeWalk::ElementContainingPoint(long left, long top, IUIAutomationElement*pCur, IUIAutomationElement** ppElem)
{
if (CancelCurrentTask())
{
return S_FALSE;
}
RECT rect;
if (SUCCEEDED(pCur->get_CurrentBoundingRectangle(&rect)))
{
if (memcmp(&rect, &rectZero, sizeof(RECT)) != 0)
{
if (left < rect.left || left > rect.right)
return S_FALSE;
if (top < rect.top || top > rect.bottom)
return S_FALSE;
}
}
CComPtr<IUIAutomationElementArray> spChildren;
REQUIRE_SUCCESS_HR(pCur->FindAll(TreeScope::TreeScope_Children, m_spFindAllCondition, &spChildren.p));
if (spChildren != nullptr)
{
int count = 0;
REQUIRE_SUCCESS_HR(spChildren->get_Length(&count));
for (int i = 0; i < count; i++)
{
CComPtr<IUIAutomationElement> spChild;
REQUIRE_SUCCESS_HR(spChildren->GetElement(i, &spChild.p));
if (spChild != nullptr && S_FALSE != ElementContainingPoint(left, top, spChild, ppElem))
{
return S_OK;
}
}
}
spChildren.Release();
REQUIRE_SUCCESS_HR(pCur->FindAll(TreeScope::TreeScope_Subtree, m_spFindAllCondition, &spChildren.p));
if (spChildren == nullptr)
return S_FALSE;
int countAll = 0;
REQUIRE_SUCCESS_HR(spChildren->get_Length(&countAll));
double areaMin = 1E12;
for (int i = 0; i < countAll; i++)
{
CComPtr<IUIAutomationElement> spChild;
REQUIRE_SUCCESS_HR(spChildren->GetElement(i, &spChild.p));
{
if (spChild != nullptr && SUCCEEDED(spChild->get_CurrentBoundingRectangle(&rect)))
{
if (rect.left <= left && left <= rect.right)
{
if (rect.top <= top && top <= rect.bottom)
{
double area = ((double)rect.right - (double)rect.left) * ((double)rect.bottom - (double)rect.top);
if (area < areaMin)
{
areaMin = area;
*ppElem = spChild;
}
}
}
}
}
}
if (*ppElem != NULL)
{
(*ppElem)->AddRef();
return S_OK;
}
else
{
return E_FAIL;
}
}