Fix deleting "embedded" toolbar from its own event handler
When we create a toolbar from within the event handler of another toolbar several times (so we have a chain of embedded toolbars) and the last toolbar is destroyed, gs_liveToolbar variable is reset in its dtor what prevents from executing the part of code in MSWCommand() for other existing toolbars if they are still in their event handlers too (still executing OnLeftClick() function). This may happen when toolbars are created in the chain of modal dialog boxes. To prevent this interference between the toolbars from occurring we have to keep track of all of active toolbars in the chain instead of keeping track of only the last one. Closes #18309.
This commit is contained in:
@@ -48,6 +48,7 @@
|
|||||||
#include "wx/dcclient.h"
|
#include "wx/dcclient.h"
|
||||||
#include "wx/rawbmp.h"
|
#include "wx/rawbmp.h"
|
||||||
#include "wx/scopedarray.h"
|
#include "wx/scopedarray.h"
|
||||||
|
#include "wx/stack.h"
|
||||||
|
|
||||||
#include <windowsx.h> // needed by GET_X_LPARAM and GET_Y_LPARAM macros
|
#include <windowsx.h> // needed by GET_X_LPARAM and GET_Y_LPARAM macros
|
||||||
|
|
||||||
@@ -132,9 +133,12 @@ wxEND_EVENT_TABLE()
|
|||||||
// module globals
|
// module globals
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// This is used to check if the toolbar itself doesn't get destroyed while
|
namespace
|
||||||
// handling its event.
|
{
|
||||||
static wxToolBar* gs_liveToolbar = NULL;
|
// Global stack used to track all active toolbars in the chain to check if
|
||||||
|
// the toolbar itself doesn't get destroyed while handling its event.
|
||||||
|
wxStack<wxToolBar*> gs_liveToolbars;
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// private classes
|
// private classes
|
||||||
@@ -526,8 +530,8 @@ void wxToolBar::Recreate()
|
|||||||
wxToolBar::~wxToolBar()
|
wxToolBar::~wxToolBar()
|
||||||
{
|
{
|
||||||
// Indicate to the code in MSWCommand() that the toolbar is destroyed.
|
// Indicate to the code in MSWCommand() that the toolbar is destroyed.
|
||||||
if ( gs_liveToolbar == this )
|
if ( !gs_liveToolbars.empty() && gs_liveToolbars.top() == this )
|
||||||
gs_liveToolbar = NULL;
|
gs_liveToolbars.pop();
|
||||||
|
|
||||||
// we must refresh the frame size when the toolbar is deleted but the frame
|
// we must refresh the frame size when the toolbar is deleted but the frame
|
||||||
// is not - otherwise toolbar leaves a hole in the place it used to occupy
|
// is not - otherwise toolbar leaves a hole in the place it used to occupy
|
||||||
@@ -1503,18 +1507,18 @@ bool wxToolBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id_)
|
|||||||
// global variable: if it gets reset from our dtor, we will know that the
|
// global variable: if it gets reset from our dtor, we will know that the
|
||||||
// toolbar was destroyed by this handler and that we can't use this object
|
// toolbar was destroyed by this handler and that we can't use this object
|
||||||
// any more.
|
// any more.
|
||||||
gs_liveToolbar = this;
|
gs_liveToolbars.push(this);
|
||||||
|
|
||||||
bool allowLeftClick = OnLeftClick(id, toggled);
|
bool allowLeftClick = OnLeftClick(id, toggled);
|
||||||
|
|
||||||
if ( gs_liveToolbar != this )
|
if ( gs_liveToolbars.empty() || gs_liveToolbars.top() != this )
|
||||||
{
|
{
|
||||||
// Bail out, we can't touch any member fields in the already
|
// Bail out, we can't touch any member fields in the already
|
||||||
// destroyed object anyhow.
|
// destroyed object anyhow.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_liveToolbar = NULL;
|
gs_liveToolbars.pop();
|
||||||
|
|
||||||
// Check if the tool hasn't been deleted in the event handler (notice that
|
// Check if the tool hasn't been deleted in the event handler (notice that
|
||||||
// it's also possible that this tool was deleted and a new tool with the
|
// it's also possible that this tool was deleted and a new tool with the
|
||||||
|
Reference in New Issue
Block a user