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:
Vadim Zeitlin
2005-01-19 02:31:09 +00:00
parent e3c55eb333
commit 51e4e26670
2 changed files with 57 additions and 95 deletions

View File

@@ -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() ;

View File

@@ -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