Take disabled windows into account in wxFindWindowAtPoint() in wxMSW.
Use ChildWindowFromPointEx(CWP_SKIPINVISIBLE) to ensure that we find the disabled children (by not using CWP_SKIPDISABLED). Add a unit test to check for the correct behaviour in all cases and document it. Closes #2942. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70794 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
7cd60fb938
commit
e18a74e240
@ -404,6 +404,9 @@ void wxEnableTopLevelWindows(bool enable = true);
|
||||
Find the deepest window at the given mouse position in screen coordinates,
|
||||
returning the window if found, or @NULL if not.
|
||||
|
||||
This function takes child windows at the given position into account even
|
||||
if they are disabled. The hidden children are however skipped by it.
|
||||
|
||||
@header{wx/utils.h}
|
||||
*/
|
||||
wxWindow* wxFindWindowAtPoint(const wxPoint& pt);
|
||||
|
@ -7205,6 +7205,14 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
|
||||
pt2.y = pt.y;
|
||||
|
||||
HWND hWnd = ::WindowFromPoint(pt2);
|
||||
if ( hWnd )
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
return wxGetWindowFromHWND((WXHWND)hWnd);
|
||||
}
|
||||
|
@ -17,12 +17,15 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/gdicmn.h"
|
||||
#include "wx/filefn.h"
|
||||
#endif // !PCH
|
||||
|
||||
#include "wx/defs.h"
|
||||
#include "wx/app.h"
|
||||
#include "wx/button.h"
|
||||
#include "wx/clipbrd.h"
|
||||
#include "wx/dataobj.h"
|
||||
|
||||
@ -40,11 +43,13 @@ private:
|
||||
CPPUNIT_TEST( DisplaySize );
|
||||
CPPUNIT_TEST( URLDataObject );
|
||||
CPPUNIT_TEST( ParseFileDialogFilter );
|
||||
CPPUNIT_TEST( FindWindowAtPoint );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void DisplaySize();
|
||||
void URLDataObject();
|
||||
void ParseFileDialogFilter();
|
||||
void FindWindowAtPoint();
|
||||
|
||||
DECLARE_NO_COPY_CLASS(MiscGUIFuncsTestCase)
|
||||
};
|
||||
@ -129,3 +134,46 @@ void MiscGUIFuncsTestCase::ParseFileDialogFilter()
|
||||
);
|
||||
}
|
||||
|
||||
void MiscGUIFuncsTestCase::FindWindowAtPoint()
|
||||
{
|
||||
wxWindow* const parent = wxTheApp->GetTopWindow();
|
||||
CPPUNIT_ASSERT( parent );
|
||||
|
||||
CPPUNIT_ASSERT_MESSAGE
|
||||
(
|
||||
"No window for a point outside of the window",
|
||||
!wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(900, 900)))
|
||||
);
|
||||
|
||||
wxWindow* const btn1 = new wxButton(parent, wxID_ANY, "1", wxPoint(10, 10));
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE
|
||||
(
|
||||
"Point over a child control corresponds to it",
|
||||
btn1,
|
||||
wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(11, 11)))
|
||||
);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE
|
||||
(
|
||||
"Point outside of any child control returns the TLW itself",
|
||||
parent,
|
||||
wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(5, 5)))
|
||||
);
|
||||
|
||||
wxWindow* const btn2 = new wxButton(parent, wxID_ANY, "2", wxPoint(10, 90));
|
||||
btn2->Disable();
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE
|
||||
(
|
||||
"Point over a disabled child control still corresponds to it",
|
||||
btn2,
|
||||
wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(11, 91)))
|
||||
);
|
||||
|
||||
btn2->Hide();
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE
|
||||
(
|
||||
"Point over a hidden child control doesn't take it into account",
|
||||
parent,
|
||||
wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(11, 91)))
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user