// set the associated frame, it is used to reset its view when we're
// destroyed
- void SetDocChildFrame(wxDocChildFrameAnyBase *docChildFrame)
- {
- m_docChildFrame = docChildFrame;
- }
+ void SetDocChildFrame(wxDocChildFrameAnyBase *docChildFrame);
protected:
// hook the document into event handlers chain here
class WXDLLIMPEXP_CORE wxDocChildFrameAnyBase
{
public:
- wxDocChildFrameAnyBase(wxDocument *doc, wxView *view)
+ wxDocChildFrameAnyBase(wxDocument *doc, wxView *view, wxWindow *win)
+ : m_win(win)
{
m_childDocument = doc;
m_childView = view;
void SetDocument(wxDocument *doc) { m_childDocument = doc; }
void SetView(wxView *view) { m_childView = view; }
+ wxWindow *GetWindow() const { return m_win; }
+
protected:
// we're not a wxEvtHandler but we provide this wxEvtHandler-like function
// which is called from TryBefore() of the derived classes to give our view
wxDocument* m_childDocument;
wxView* m_childView;
+ // the associated window: having it here is not terribly elegant but it
+ // allows us to avoid having any virtual functions in this class
+ wxWindow * const m_win;
+
+
wxDECLARE_NO_COPY_CLASS(wxDocChildFrameAnyBase);
};
long style = wxDEFAULT_FRAME_STYLE,
const wxString& name = wxFrameNameStr)
: BaseClass(parent, id, title, pos, size, style, name),
- wxDocChildFrameAnyBase(doc, view)
+ wxDocChildFrameAnyBase(doc, view, this)
{
- if ( view )
- view->SetFrame(this);
-
this->Connect(wxEVT_ACTIVATE,
wxActivateEventHandler(wxDocChildFrameAny::OnActivate));
this->Connect(wxEVT_CLOSE_WINDOW,
// box which would result in an activation event for m_docChildFrame and so
// could reactivate the view being destroyed -- unless we reset it first
if ( m_docChildFrame && m_docChildFrame->GetView() == this )
+ {
+ // prevent it from doing anything with us
m_docChildFrame->SetView(NULL);
+ // it doesn't make sense to leave the frame alive if its associated
+ // view doesn't exist any more so unconditionally close it as well
+ //
+ // notice that we only get here if m_docChildFrame is non-NULL in the
+ // first place and it will be always NULL if we're deleted because our
+ // frame was closed, so this only catches the case of directly deleting
+ // the view, as it happens if its creation fails in wxDocTemplate::
+ // CreateView() for example
+ m_docChildFrame->GetWindow()->Destroy();
+ }
+
if ( m_viewDocument )
m_viewDocument->RemoveView(this);
}
+void wxView::SetDocChildFrame(wxDocChildFrameAnyBase *docChildFrame)
+{
+ SetFrame(docChildFrame ? docChildFrame->GetWindow() : NULL);
+ m_docChildFrame = docChildFrame;
+}
+
bool wxView::TryBefore(wxEvent& event)
{
wxDocument * const doc = GetDocument();
}
m_childView->Activate(false);
+
+ // it is important to reset m_childView frame pointer to NULL before
+ // deleting it because while normally it is the frame which deletes the
+ // view when it's closed, the view also closes the frame if it is
+ // deleted directly not by us as indicated by its doc child frame
+ // pointer still being set
+ m_childView->SetDocChildFrame(NULL);
delete m_childView;
m_childView = NULL;
}