Fall back on ::GetMessagePos() if ::GetCursorPos() fails under MSW.

In some rare but reproducible cases GetCursorPos() can fail and return without
filling in the provided point. Fall back to GetMessagePos() if this happens:
this is not ideal but clearly better than using uninitialized position or hard
coding something like (0, 0).

Closes #13664.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69758 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2011-11-14 12:51:53 +00:00
parent 3e6807d701
commit d6c37f5bc4
6 changed files with 29 additions and 54 deletions

View File

@@ -923,6 +923,9 @@ WXDLLIMPEXP_BASE wxWinVersion wxGetWinVersion();
extern HCURSOR wxGetCurrentBusyCursor(); // from msw/utils.cpp extern HCURSOR wxGetCurrentBusyCursor(); // from msw/utils.cpp
extern const wxCursor *wxGetGlobalCursor(); // from msw/cursor.cpp extern const wxCursor *wxGetGlobalCursor(); // from msw/cursor.cpp
// GetCursorPos can fail without populating the POINT. This falls back to GetMessagePos.
WXDLLIMPEXP_CORE void wxGetCursorPosMSW(POINT* pt);
WXDLLIMPEXP_CORE void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font); WXDLLIMPEXP_CORE void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font);
WXDLLIMPEXP_CORE void wxFillLogFont(LOGFONT *logFont, const wxFont *font); WXDLLIMPEXP_CORE void wxFillLogFont(LOGFONT *logFont, const wxFont *font);
WXDLLIMPEXP_CORE wxFont wxCreateFontFromLogFont(const LOGFONT *logFont); WXDLLIMPEXP_CORE wxFont wxCreateFontFromLogFont(const LOGFONT *logFont);

View File

@@ -1905,9 +1905,8 @@ int WXDLLIMPEXP_CORE wxMSWGetColumnClicked(NMHDR *nmhdr, POINT *ptClick)
} }
else else
#endif //__WXWINCE__ #endif //__WXWINCE__
if ( !::GetCursorPos(ptClick) )
{ {
wxLogLastError(wxT("GetCursorPos")); wxGetCursorPosMSW(ptClick);
} }
// we need to use listctrl coordinates for the event point so this is what // we need to use listctrl coordinates for the event point so this is what
@@ -2323,7 +2322,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
else else
#endif //__WXWINCE__ #endif //__WXWINCE__
{ {
::GetCursorPos(&(lvhti.pt)); wxGetCursorPosMSW(&(lvhti.pt));
} }
::ScreenToClient(GetHwnd(), &lvhti.pt); ::ScreenToClient(GetHwnd(), &lvhti.pt);

View File

@@ -3645,7 +3645,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
case NM_RCLICK: case NM_RCLICK:
{ {
TV_HITTESTINFO tvhti; TV_HITTESTINFO tvhti;
::GetCursorPos(&tvhti.pt); wxGetCursorPosMSW(&tvhti.pt);
::ScreenToClient(GetHwnd(), &tvhti.pt); ::ScreenToClient(GetHwnd(), &tvhti.pt);
if ( TreeView_HitTest(GetHwnd(), &tvhti) ) if ( TreeView_HitTest(GetHwnd(), &tvhti) )
{ {

View File

@@ -49,7 +49,7 @@ DWORD EventTypeForMouseButton(int button, bool isDown)
bool wxUIActionSimulator::MouseDown(int button) bool wxUIActionSimulator::MouseDown(int button)
{ {
POINT p; POINT p;
GetCursorPos(&p); wxGetCursorPosMSW(&p);
mouse_event(EventTypeForMouseButton(button, true), p.x, p.y, 0, 0); mouse_event(EventTypeForMouseButton(button, true), p.x, p.y, 0, 0);
return true; return true;
} }
@@ -71,7 +71,7 @@ bool wxUIActionSimulator::MouseMove(long x, long y)
bool wxUIActionSimulator::MouseUp(int button) bool wxUIActionSimulator::MouseUp(int button)
{ {
POINT p; POINT p;
GetCursorPos(&p); wxGetCursorPosMSW(&p);
mouse_event(EventTypeForMouseButton(button, false), p.x, p.y, 0, 0); mouse_event(EventTypeForMouseButton(button, false), p.x, p.y, 0, 0);
return true; return true;
} }

View File

@@ -113,7 +113,7 @@ bool wxCheckForInterrupt(wxWindow *wnd)
void wxGetMousePosition( int* x, int* y ) void wxGetMousePosition( int* x, int* y )
{ {
POINT pt; POINT pt;
GetCursorPos( & pt ); wxGetCursorPosMSW( & pt );
if ( x ) *x = pt.x; if ( x ) *x = pt.x;
if ( y ) *y = pt.y; if ( y ) *y = pt.y;
} }

View File

@@ -321,20 +321,23 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent)
#endif // !__WXWINCE__ #endif // !__WXWINCE__
#ifdef __WXWINCE__ // GetCursorPos can return an error, so use this function
// On Windows CE, GetCursorPos can return an error, so use this function // instead.
// instead // Error originally observed with WinCE, but later using Remote Desktop
bool GetCursorPosWinCE(POINT* pt) // to connect to XP.
void wxGetCursorPosMSW(POINT* pt)
{ {
if (!GetCursorPos(pt)) if (!GetCursorPos(pt))
{ {
DWORD pos = GetMessagePos(); #ifdef __WXWINCE__
pt->x = LOWORD(pos); wxLogLastError(wxT("GetCursorPos"));
pt->y = HIWORD(pos);
}
return true;
}
#endif #endif
DWORD pos = GetMessagePos();
// the coordinates may be negative in multi-monitor systems
pt->x = GET_X_LPARAM(pos);
pt->y = GET_Y_LPARAM(pos);
}
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// event tables // event tables
@@ -852,11 +855,7 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
HWND hWnd = GetHwnd(); HWND hWnd = GetHwnd();
POINT point; POINT point;
#ifdef __WXWINCE__ ::wxGetCursorPosMSW(&point);
::GetCursorPosWinCE(&point);
#else
::GetCursorPos(&point);
#endif
RECT rect = wxGetWindowRect(hWnd); RECT rect = wxGetWindowRect(hWnd);
@@ -875,11 +874,7 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
// under the cursor and ask it to set its cursor itself as only it // under the cursor and ask it to set its cursor itself as only it
// knows what it is. // knows what it is.
POINT pt; POINT pt;
if ( !::GetCursorPos(&pt) ) wxGetCursorPosMSW(&pt);
{
wxLogLastError(wxT("GetCursorPos"));
return false;
}
const wxWindowMSW* win = wxFindWindowAtPoint(wxPoint(pt.x, pt.y)); const wxWindowMSW* win = wxFindWindowAtPoint(wxPoint(pt.x, pt.y));
if ( !win ) if ( !win )
@@ -1517,11 +1512,7 @@ bool wxWindowMSW::IsMouseInWindow() const
{ {
// get the mouse position // get the mouse position
POINT pt; POINT pt;
#ifdef __WXWINCE__ wxGetCursorPosMSW(&pt);
::GetCursorPosWinCE(&pt);
#else
::GetCursorPos(&pt);
#endif
// find the window which currently has the cursor and go up the window // find the window which currently has the cursor and go up the window
// chain until we find this window - or exhaust it // chain until we find this window - or exhaust it
@@ -4204,14 +4195,7 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
// first ask the user code - it may wish to set the cursor in some very // first ask the user code - it may wish to set the cursor in some very
// specific way (for example, depending on the current position) // specific way (for example, depending on the current position)
POINT pt; POINT pt;
#ifdef __WXWINCE__ wxGetCursorPosMSW(&pt);
if ( !::GetCursorPosWinCE(&pt))
#else
if ( !::GetCursorPos(&pt) )
#endif
{
wxLogLastError(wxT("GetCursorPos"));
}
int x = pt.x, int x = pt.x,
y = pt.y; y = pt.y;
@@ -5628,14 +5612,7 @@ void wxWindowMSW::GenerateMouseLeave()
state |= MK_RBUTTON; state |= MK_RBUTTON;
POINT pt; POINT pt;
#ifdef __WXWINCE__ wxGetCursorPosMSW(&pt);
if ( !::GetCursorPosWinCE(&pt) )
#else
if ( !::GetCursorPos(&pt) )
#endif
{
wxLogLastError(wxT("GetCursorPos"));
}
// we need to have client coordinates here for symmetry with // we need to have client coordinates here for symmetry with
// wxEVT_ENTER_WINDOW // wxEVT_ENTER_WINDOW
@@ -6521,7 +6498,7 @@ wxMouseState wxGetMouseState()
{ {
wxMouseState ms; wxMouseState ms;
POINT pt; POINT pt;
GetCursorPos( &pt ); wxGetCursorPosMSW(&pt);
ms.SetX(pt.x); ms.SetX(pt.x);
ms.SetY(pt.y); ms.SetY(pt.y);
@@ -7224,11 +7201,7 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
wxPoint wxGetMousePosition() wxPoint wxGetMousePosition()
{ {
POINT pt; POINT pt;
#ifdef __WXWINCE__ wxGetCursorPosMSW(&pt);
GetCursorPosWinCE(&pt);
#else
GetCursorPos( & pt );
#endif
return wxPoint(pt.x, pt.y); return wxPoint(pt.x, pt.y);
} }