reenabled WM_MOUSELEAVE event handling (patch 1104551); moved duplicated code in its handler in a new GenerateMouseLeave() method
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31480 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -411,6 +411,9 @@ public:
|
|||||||
// check if mouse is in the window
|
// check if mouse is in the window
|
||||||
bool IsMouseInWindow() const;
|
bool IsMouseInWindow() const;
|
||||||
|
|
||||||
|
// synthesize a wxEVT_LEAVE_WINDOW event and set m_mouseInWindow to false
|
||||||
|
void GenerateMouseLeave();
|
||||||
|
|
||||||
// virtual function for implementing internal idle
|
// virtual function for implementing internal idle
|
||||||
// behaviour
|
// behaviour
|
||||||
virtual void OnInternalIdle() ;
|
virtual void OnInternalIdle() ;
|
||||||
|
@@ -1243,6 +1243,7 @@ bool wxWindowMSW::IsMouseInWindow() const
|
|||||||
|
|
||||||
void wxWindowMSW::OnInternalIdle()
|
void wxWindowMSW::OnInternalIdle()
|
||||||
{
|
{
|
||||||
|
#ifdef __WXWINCE__
|
||||||
// Check if we need to send a LEAVE event
|
// Check if we need to send a LEAVE event
|
||||||
if ( m_mouseInWindow )
|
if ( m_mouseInWindow )
|
||||||
{
|
{
|
||||||
@@ -1250,44 +1251,10 @@ void wxWindowMSW::OnInternalIdle()
|
|||||||
// or doesn't have mouse capture
|
// or doesn't have mouse capture
|
||||||
if ( !IsMouseInWindow() )
|
if ( !IsMouseInWindow() )
|
||||||
{
|
{
|
||||||
// Generate a LEAVE event
|
GenerateMouseLeave();
|
||||||
m_mouseInWindow = false;
|
|
||||||
|
|
||||||
// Unfortunately the mouse button and keyboard state may have
|
|
||||||
// changed by the time the OnInternalIdle function is called, so 'state'
|
|
||||||
// may be meaningless.
|
|
||||||
int state = 0;
|
|
||||||
if ( wxIsShiftDown() )
|
|
||||||
state |= MK_SHIFT;
|
|
||||||
if ( wxIsCtrlDown() )
|
|
||||||
state |= MK_CONTROL;
|
|
||||||
|
|
||||||
// Only the high-order bit should be tested
|
|
||||||
if ( GetKeyState( VK_LBUTTON ) & (1<<15) )
|
|
||||||
state |= MK_LBUTTON;
|
|
||||||
if ( GetKeyState( VK_MBUTTON ) & (1<<15) )
|
|
||||||
state |= MK_MBUTTON;
|
|
||||||
if ( GetKeyState( VK_RBUTTON ) & (1<<15) )
|
|
||||||
state |= MK_RBUTTON;
|
|
||||||
|
|
||||||
POINT pt;
|
|
||||||
if ( !::GetCursorPos(&pt) )
|
|
||||||
{
|
|
||||||
wxLogLastError(_T("GetCursorPos"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to have client coordinates here for symmetry with
|
|
||||||
// wxEVT_ENTER_WINDOW
|
|
||||||
RECT rect = wxGetWindowRect(GetHwnd());
|
|
||||||
pt.x -= rect.left;
|
|
||||||
pt.y -= rect.top;
|
|
||||||
|
|
||||||
wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
|
|
||||||
InitMouseEvent(event2, pt.x, pt.y, state);
|
|
||||||
|
|
||||||
(void)GetEventHandler()->ProcessEvent(event2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // !__WXWINCE__
|
||||||
|
|
||||||
if (wxUpdateUIEvent::CanUpdate(this))
|
if (wxUpdateUIEvent::CanUpdate(this))
|
||||||
UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
|
UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
|
||||||
@@ -2434,61 +2401,23 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
|
|||||||
wParam);
|
wParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Seems to be broken currently
|
#ifdef WM_MOUSELEAVE
|
||||||
#if 0 // ndef __WXWINCE__
|
|
||||||
case WM_MOUSELEAVE:
|
case WM_MOUSELEAVE:
|
||||||
{
|
|
||||||
wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
|
|
||||||
|
|
||||||
// only process this message if the mouse is not in the window,
|
|
||||||
// This can also check for children in composite windows.
|
|
||||||
// however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
|
|
||||||
// if the mouse does not enter the window from it's child before
|
|
||||||
// leaving the scope of the window. ( perhaps this can be picked
|
|
||||||
// up in the OnIdle code as before, for this special case )
|
|
||||||
if ( /*IsComposite() && */ !IsMouseInWindow() )
|
|
||||||
{
|
{
|
||||||
m_mouseInWindow = false;
|
// filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least)
|
||||||
|
if ( m_mouseInWindow )
|
||||||
// Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
|
|
||||||
int state = 0;
|
|
||||||
if ( wxIsShiftDown() )
|
|
||||||
state |= MK_SHIFT;
|
|
||||||
if ( wxIsCtrlDown() )
|
|
||||||
state |= MK_CONTROL;
|
|
||||||
if ( GetKeyState( VK_LBUTTON ) )
|
|
||||||
state |= MK_LBUTTON;
|
|
||||||
if ( GetKeyState( VK_MBUTTON ) )
|
|
||||||
state |= MK_MBUTTON;
|
|
||||||
if ( GetKeyState( VK_RBUTTON ) )
|
|
||||||
state |= MK_RBUTTON;
|
|
||||||
|
|
||||||
POINT pt;
|
|
||||||
if ( !::GetCursorPos(&pt) )
|
|
||||||
{
|
{
|
||||||
wxLogLastError(_T("GetCursorPos"));
|
GenerateMouseLeave();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to have client coordinates here for symmetry with
|
// always pass processed back as false, this allows the window
|
||||||
// wxEVT_ENTER_WINDOW
|
// manager to process the message too. This is needed to
|
||||||
RECT rect = wxGetWindowRect(GetHwnd());
|
// ensure windows XP themes work properly as the mouse moves
|
||||||
pt.x -= rect.left;
|
// over widgets like buttons.
|
||||||
pt.y -= rect.top;
|
processed = false;
|
||||||
|
|
||||||
wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
|
|
||||||
InitMouseEvent(event2, pt.x, pt.y, state);
|
|
||||||
|
|
||||||
(void)GetEventHandler()->ProcessEvent(event2);
|
|
||||||
}
|
}
|
||||||
// always pass processed back as false, this allows the window
|
break;
|
||||||
// manager to process the message too. This is needed to ensure
|
#endif // WM_MOUSELEAVE
|
||||||
// windows XP themes work properly as the mouse moves over widgets
|
|
||||||
// like buttons.
|
|
||||||
processed = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
// __WXWINCE__
|
|
||||||
|
|
||||||
#if wxUSE_MOUSEWHEEL
|
#if wxUSE_MOUSEWHEEL
|
||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
@@ -4395,9 +4324,6 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
|
|||||||
event.m_leftDown = (flags & MK_LBUTTON) != 0;
|
event.m_leftDown = (flags & MK_LBUTTON) != 0;
|
||||||
event.m_middleDown = (flags & MK_MBUTTON) != 0;
|
event.m_middleDown = (flags & MK_MBUTTON) != 0;
|
||||||
event.m_rightDown = (flags & MK_RBUTTON) != 0;
|
event.m_rightDown = (flags & MK_RBUTTON) != 0;
|
||||||
// event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0;
|
|
||||||
// Returns different negative values on WinME and WinNT,
|
|
||||||
// so simply test for negative value.
|
|
||||||
event.m_altDown = ::GetKeyState(VK_MENU) < 0;
|
event.m_altDown = ::GetKeyState(VK_MENU) < 0;
|
||||||
|
|
||||||
#ifndef __WXWINCE__
|
#ifndef __WXWINCE__
|
||||||
@@ -4516,7 +4442,6 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
|
|||||||
{
|
{
|
||||||
// Generate an ENTER event
|
// Generate an ENTER event
|
||||||
m_mouseInWindow = true;
|
m_mouseInWindow = true;
|
||||||
#if _WIN32_WINNT >= 0x0400
|
|
||||||
#ifndef __WXWINCE__
|
#ifndef __WXWINCE__
|
||||||
TRACKMOUSEEVENT trackinfo;
|
TRACKMOUSEEVENT trackinfo;
|
||||||
|
|
||||||
@@ -4527,8 +4452,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
|
|||||||
// appropriate TrackMouseEvent or emulate it ( win95 )
|
// appropriate TrackMouseEvent or emulate it ( win95 )
|
||||||
// else we need _WIN32_WINNT >= 0x0400
|
// else we need _WIN32_WINNT >= 0x0400
|
||||||
_TrackMouseEvent(&trackinfo);
|
_TrackMouseEvent(&trackinfo);
|
||||||
#endif
|
#endif // __WXWINCE__
|
||||||
#endif
|
|
||||||
wxMouseEvent event(wxEVT_ENTER_WINDOW);
|
wxMouseEvent event(wxEVT_ENTER_WINDOW);
|
||||||
InitMouseEvent(event, x, y, flags);
|
InitMouseEvent(event, x, y, flags);
|
||||||
|
|
||||||
@@ -4583,14 +4507,49 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
|
|||||||
event.m_linesPerAction = s_linesPerRotation;
|
event.m_linesPerAction = s_linesPerRotation;
|
||||||
return GetEventHandler()->ProcessEvent(event);
|
return GetEventHandler()->ProcessEvent(event);
|
||||||
|
|
||||||
#else
|
#else // !wxUSE_MOUSEWHEEL
|
||||||
(void) wParam;
|
wxUnusedVar(wParam);
|
||||||
(void) lParam;
|
wxUnusedVar(lParam);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWindowMSW::GenerateMouseLeave()
|
||||||
|
{
|
||||||
|
m_mouseInWindow = false;
|
||||||
|
|
||||||
|
int state = 0;
|
||||||
|
if ( wxIsShiftDown() )
|
||||||
|
state |= MK_SHIFT;
|
||||||
|
if ( wxIsCtrlDown() )
|
||||||
|
state |= MK_CONTROL;
|
||||||
|
|
||||||
|
// Only the high-order bit should be tested
|
||||||
|
if ( GetKeyState( VK_LBUTTON ) & (1<<15) )
|
||||||
|
state |= MK_LBUTTON;
|
||||||
|
if ( GetKeyState( VK_MBUTTON ) & (1<<15) )
|
||||||
|
state |= MK_MBUTTON;
|
||||||
|
if ( GetKeyState( VK_RBUTTON ) & (1<<15) )
|
||||||
|
state |= MK_RBUTTON;
|
||||||
|
|
||||||
|
POINT pt;
|
||||||
|
if ( !::GetCursorPos(&pt) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("GetCursorPos"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need to have client coordinates here for symmetry with
|
||||||
|
// wxEVT_ENTER_WINDOW
|
||||||
|
RECT rect = wxGetWindowRect(GetHwnd());
|
||||||
|
pt.x -= rect.left;
|
||||||
|
pt.y -= rect.top;
|
||||||
|
|
||||||
|
wxMouseEvent event(wxEVT_LEAVE_WINDOW);
|
||||||
|
InitMouseEvent(event, pt.x, pt.y, state);
|
||||||
|
|
||||||
|
(void)GetEventHandler()->ProcessEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// keyboard handling
|
// keyboard handling
|
||||||
|
Reference in New Issue
Block a user