Return NULL from wxWindow::GetCapture() when the capture is being lost.
Make GetCapture() return NULL during wxEVT_MOUSE_CAPTURE_{LOST,CHANGED} events processing in wxMSW to help their handlers to avoid calling ReleaseCapture(): this shouldn't be done as the mouse capture is being lost anyhow and results in reentrancy problems between NotifyCaptureLost() and ReleaseCapture() if it's called. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74678 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -59,6 +59,7 @@
|
|||||||
#include "wx/hashmap.h"
|
#include "wx/hashmap.h"
|
||||||
#include "wx/evtloop.h"
|
#include "wx/evtloop.h"
|
||||||
#include "wx/power.h"
|
#include "wx/power.h"
|
||||||
|
#include "wx/scopeguard.h"
|
||||||
#include "wx/sysopt.h"
|
#include "wx/sysopt.h"
|
||||||
|
|
||||||
#if wxUSE_DRAG_AND_DROP
|
#if wxUSE_DRAG_AND_DROP
|
||||||
@@ -240,6 +241,9 @@ EraseBgHooks gs_eraseBgHooks;
|
|||||||
// needed.
|
// needed.
|
||||||
int gs_modalEntryWindowCount = 0;
|
int gs_modalEntryWindowCount = 0;
|
||||||
|
|
||||||
|
// Indicates whether we are currently processing WM_CAPTURECHANGED message.
|
||||||
|
bool gs_insideCaptureChanged = false;
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -804,6 +808,13 @@ void wxWindowMSW::DoReleaseMouse()
|
|||||||
|
|
||||||
/* static */ wxWindow *wxWindowBase::GetCapture()
|
/* static */ wxWindow *wxWindowBase::GetCapture()
|
||||||
{
|
{
|
||||||
|
// When we receive WM_CAPTURECHANGED message, ::GetCapture() still returns
|
||||||
|
// the HWND that is losing the mouse capture. But as we must not release
|
||||||
|
// the capture for it (it's going to happen anyhow), pretend that there is
|
||||||
|
// no capture any more.
|
||||||
|
if ( gs_insideCaptureChanged )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
HWND hwnd = ::GetCapture();
|
HWND hwnd = ::GetCapture();
|
||||||
return hwnd ? wxFindWinFromHandle(hwnd) : NULL;
|
return hwnd ? wxFindWinFromHandle(hwnd) : NULL;
|
||||||
}
|
}
|
||||||
@@ -4544,6 +4555,12 @@ bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
|
|||||||
|
|
||||||
bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
|
bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
|
||||||
{
|
{
|
||||||
|
// Ensure that wxWindow::GetCapture() returns NULL if called from the event
|
||||||
|
// handlers invoked below. This is necessary to avoid wrongly calling
|
||||||
|
// ReleaseMouse() when we're already losing the mouse capture anyhow.
|
||||||
|
gs_insideCaptureChanged = true;
|
||||||
|
wxON_BLOCK_EXIT_SET(gs_insideCaptureChanged, false);
|
||||||
|
|
||||||
// notify windows on the capture stack about lost capture
|
// notify windows on the capture stack about lost capture
|
||||||
// (see http://sourceforge.net/tracker/index.php?func=detail&aid=1153662&group_id=9863&atid=109863):
|
// (see http://sourceforge.net/tracker/index.php?func=detail&aid=1153662&group_id=9863&atid=109863):
|
||||||
wxWindowBase::NotifyCaptureLost();
|
wxWindowBase::NotifyCaptureLost();
|
||||||
|
Reference in New Issue
Block a user