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,
|
Find the deepest window at the given mouse position in screen coordinates,
|
||||||
returning the window if found, or @NULL if not.
|
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}
|
@header{wx/utils.h}
|
||||||
*/
|
*/
|
||||||
wxWindow* wxFindWindowAtPoint(const wxPoint& pt);
|
wxWindow* wxFindWindowAtPoint(const wxPoint& pt);
|
||||||
|
@ -7205,6 +7205,14 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
|
|||||||
pt2.y = pt.y;
|
pt2.y = pt.y;
|
||||||
|
|
||||||
HWND hWnd = ::WindowFromPoint(pt2);
|
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);
|
return wxGetWindowFromHWND((WXHWND)hWnd);
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,15 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/defs.h"
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/gdicmn.h"
|
#include "wx/gdicmn.h"
|
||||||
#include "wx/filefn.h"
|
#include "wx/filefn.h"
|
||||||
#endif // !PCH
|
#endif // !PCH
|
||||||
|
|
||||||
#include "wx/defs.h"
|
#include "wx/app.h"
|
||||||
|
#include "wx/button.h"
|
||||||
#include "wx/clipbrd.h"
|
#include "wx/clipbrd.h"
|
||||||
#include "wx/dataobj.h"
|
#include "wx/dataobj.h"
|
||||||
|
|
||||||
@ -40,11 +43,13 @@ private:
|
|||||||
CPPUNIT_TEST( DisplaySize );
|
CPPUNIT_TEST( DisplaySize );
|
||||||
CPPUNIT_TEST( URLDataObject );
|
CPPUNIT_TEST( URLDataObject );
|
||||||
CPPUNIT_TEST( ParseFileDialogFilter );
|
CPPUNIT_TEST( ParseFileDialogFilter );
|
||||||
|
CPPUNIT_TEST( FindWindowAtPoint );
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
void DisplaySize();
|
void DisplaySize();
|
||||||
void URLDataObject();
|
void URLDataObject();
|
||||||
void ParseFileDialogFilter();
|
void ParseFileDialogFilter();
|
||||||
|
void FindWindowAtPoint();
|
||||||
|
|
||||||
DECLARE_NO_COPY_CLASS(MiscGUIFuncsTestCase)
|
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