added wxEVT_MOUSE_CAPTURE_LOST event and code for correctly handling capture loss (bug #1153662)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40391 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2006-07-31 09:27:54 +00:00
parent f9c240ec1e
commit 63e819f298
10 changed files with 184 additions and 11 deletions

View File

@@ -2334,11 +2334,17 @@ struct WXDLLEXPORT wxWindowNext
wxWindow *win;
wxWindowNext *next;
} *wxWindowBase::ms_winCaptureNext = NULL;
wxWindow *wxWindowBase::ms_winCaptureCurrent = NULL;
bool wxWindowBase::ms_winCaptureChanging = false;
void wxWindowBase::CaptureMouse()
{
wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), wx_static_cast(void*, this));
wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive CaptureMouse call?") );
ms_winCaptureChanging = true;
wxWindow *winOld = GetCapture();
if ( winOld )
{
@@ -2353,19 +2359,28 @@ void wxWindowBase::CaptureMouse()
//else: no mouse capture to save
DoCaptureMouse();
ms_winCaptureCurrent = (wxWindow*)this;
ms_winCaptureChanging = false;
}
void wxWindowBase::ReleaseMouse()
{
wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), wx_static_cast(void*, this));
wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive ReleaseMouse call?") );
wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") );
ms_winCaptureChanging = true;
DoReleaseMouse();
ms_winCaptureCurrent = NULL;
if ( ms_winCaptureNext )
{
((wxWindowBase*)ms_winCaptureNext->win)->DoCaptureMouse();
ms_winCaptureCurrent = ms_winCaptureNext->win;
wxWindowNext *item = ms_winCaptureNext;
ms_winCaptureNext = item->next;
@@ -2373,11 +2388,51 @@ void wxWindowBase::ReleaseMouse()
}
//else: stack is empty, no previous capture
ms_winCaptureChanging = false;
wxLogTrace(_T("mousecapture"),
(const wxChar *) _T("After ReleaseMouse() mouse is captured by %p"),
wx_static_cast(void*, GetCapture()));
}
static void DoNotifyWindowAboutCaptureLost(wxWindow *win)
{
wxMouseCaptureLostEvent event(win->GetId());
event.SetEventObject(win);
bool processed = win->GetEventHandler()->ProcessEvent(event);
wxASSERT_MSG( processed,
_T("window that captured mouse didn't process wxEVT_MOUSE_CAPTURE_LOST") );
}
/* static */
void wxWindowBase::NotifyCaptureLost(wxWindow *gainedCapture)
{
// don't do anything if capture lost was expected, i.e. resulted from
// a wx call to ReleaseMouse or CaptureMouse:
if ( ms_winCaptureChanging )
return;
// if the capture was lost unexpectedly, notify every window that has
// capture (on stack or current) about it and clear the stack:
if ( ms_winCaptureCurrent )
{
DoNotifyWindowAboutCaptureLost(ms_winCaptureCurrent);
ms_winCaptureCurrent = NULL;
}
while ( ms_winCaptureNext )
{
wxWindowNext *item = ms_winCaptureNext;
ms_winCaptureNext = item->next;
DoNotifyWindowAboutCaptureLost(item->win);
delete item;
}
}
#if wxUSE_HOTKEY
bool