From a79a6671e405bc0630e819e3c2a2c1f3fea6d2e9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 21 Jan 2009 00:14:30 +0000 Subject: [PATCH] send destroy events for children before they're fully destroyed; document SendDestroyEvent() and explain when to call it git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58252 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- interface/wx/event.h | 30 +++++++++++++++++++++--------- interface/wx/window.h | 9 +++++++++ src/common/wincmn.cpp | 12 +++++++----- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/interface/wx/event.h b/interface/wx/event.h index b7a7c5c7ce..8f76631f11 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -1061,6 +1061,9 @@ public: Constructor. */ wxWindowCreateEvent(wxWindow* win = NULL); + + /// Retutn the window being created. + wxWindow *GetWindow() const; }; @@ -2749,17 +2752,23 @@ public: /** @class wxWindowDestroyEvent - This event is sent from the wxWindow destructor wxWindow::~wxWindow() when a - window is destroyed. + This event is sent as early as possible during the window destruction + process. + + For the top level windows, as early as possible means that this is done by + wxFrame or wxDialog destructor, i.e. after the destructor of the derived + class was executed and so any methods specific to the derived class can't + be called any more from this event handler. If you need to do this, you + must call wxWindow::SendDestroyEvent() from your derived class destructor. - When a class derived from wxWindow is destroyed its destructor will have - already run by the time this event is sent. Therefore this event will not - usually be received at all. + For the child windows, this event is generated just before deleting the + window from wxWindow::Destroy() (which is also called when the parent + window is deleted) or from the window destructor if operator @c delete was + used directly (which is not recommended for this very reason). - To receive this event wxEvtHandler::Connect() must be used (using an event - table macro will not work). Since it is received after the destructor has run, - an object should not handle its own wxWindowDestroyEvent, but it can be used - to get notification of the destruction of another window. + It is usually pointless to handle this event in the window itself but it ca + be very useful to receive notifications about the window destruction in the + parent window or in any other object interested in this window. @library{wxcore} @category{events} @@ -2773,6 +2782,9 @@ public: Constructor. */ wxWindowDestroyEvent(wxWindow* win = NULL); + + /// Retutn the window being destroyed. + wxWindow *GetWindow() const; }; diff --git a/interface/wx/window.h b/interface/wx/window.h index 71b0f46344..d2ed1799a0 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -2815,6 +2815,15 @@ protected: @deprecated @todo provide deprecation description */ virtual void SetInitialBestSize(const wxSize& size); + + /** + Generate wxWindowDestroyEvent for this window. + + This is called by the window itself when it is being destroyed and + usually there is no need to call it but see wxWindowDestroyEvent for + explanations of when you might want to do it. + */ + void SendDestroyEvent(); }; diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 5192410234..964585411a 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -407,6 +407,8 @@ void wxWindowBase::SendDestroyEvent() bool wxWindowBase::Destroy() { + SendDestroyEvent(); + delete this; return true; @@ -435,11 +437,11 @@ bool wxWindowBase::DestroyChildren() wxWindow *child = node->GetData(); - // note that we really want to call delete and not ->Destroy() here - // because we want to delete the child immediately, before we are - // deleted, and delayed deletion would result in problems as our (top - // level) child could outlive its parent - delete child; + // note that we really want to delete it immediately so don't call the + // possible overridden Destroy() version which might not delete the + // child immediately resulting in problems with our (top level) child + // outliving its parent + child->wxWindowBase::Destroy(); wxASSERT_MSG( !GetChildren().Find(child), wxT("child didn't remove itself using RemoveChild()") ); -- 2.45.2