Fix wxFindWindowAtPoint() with nested windows in wxMSW.

Return the deepest child of the window and not the first one as this function
needs to return the window that is at the top of Z-order.

Closes #14591.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72470 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2012-09-13 17:12:42 +00:00
parent c7453fba64
commit 0825f0ba2b
2 changed files with 27 additions and 3 deletions

View File

@ -7215,9 +7215,21 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
{
// WindowFromPoint() ignores the disabled children but we're supposed
// to take them into account, so check if we have a child at this
// coordinate.
::ScreenToClient(hWnd, &pt2);
hWnd = ::ChildWindowFromPointEx(hWnd, pt2, CWP_SKIPINVISIBLE);
// coordinate using ChildWindowFromPointEx().
for ( ;; )
{
pt2.x = pt.x;
pt2.y = pt.y;
::ScreenToClient(hWnd, &pt2);
HWND child = ::ChildWindowFromPointEx(hWnd, pt2, CWP_SKIPINVISIBLE);
if ( child == hWnd || !child )
break;
// ChildWindowFromPointEx() only examines the immediate children
// but we want to get the deepest (top in Z-order) one, so continue
// iterating for as long as it finds anything.
hWnd = child;
}
}
return wxGetWindowFromHWND((WXHWND)hWnd);

View File

@ -177,6 +177,18 @@ void MiscGUIFuncsTestCase::FindWindowAtPoint()
wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(11, 91)))
);
btn2->Show();
wxWindow* btn3 = new wxButton(btn2, wxID_ANY, "3", wxPoint(0, 0));
btn3->Disable();
CPPUNIT_ASSERT_EQUAL_MESSAGE
(
"Point over recursive disabled child controls corresponds to deepest child",
btn3,
wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(11, 91)))
);
wxASSERT(wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(11, 91))) == btn3);
wxDELETE(btn1);
wxDELETE(btn3); // delete child before parent
wxDELETE(btn2);
}