]> git.saurik.com Git - wxWidgets.git/blobdiff - docs/latex/wx/tdelwin.tex
Bug 1099143 and more occurences of the same set vs. get mistakes.
[wxWidgets.git] / docs / latex / wx / tdelwin.tex
index 33e368dd68c5b38e08d2d98e43a639c6bd6f7a36..ff8b02df276f04478c83e46cf6823f6277d15700 100644 (file)
@@ -3,48 +3,56 @@
 Classes: \helpref{wxCloseEvent}{wxcloseevent}, \helpref{wxWindow}{wxwindow}
 
 Window deletion can be a confusing subject, so this overview is provided
-to make it clear when and how you delete windows, or respond to user requests
+to help make it clear when and how you delete windows, or respond to user requests
 to close windows.
 
 \wxheading{What is the sequence of events in a window deletion?}
 
 When the user clicks on the system close button or system close command,
-in a frame or a dialog, wxWindows calls \helpref{wxWindow::Close}{wxwindowclose}.
+in a frame or a dialog, wxWidgets calls \helpref{wxWindow::Close}{wxwindowclose}. This
+in turn generates an EVT\_CLOSE event: see \helpref{wxCloseEvent}{wxcloseevent}.
 
-This function then generates a \helpref{wxCloseEvent}{wxcloseevent} event which
-can be handled by the application (by using an EVT\_CLOSE event table entry). It is the duty of the application to
-define a suitable event handler, and decide whether or not to destroy the window.
-If the application is for some reason forcing the application to close,
-the window should always be destroyed, otherwise there is the option to
+It is the duty of the application to define a suitable event handler, and
+decide whether or not to destroy the window.
+If the application is for some reason forcing the application to close
+(\helpref{wxCloseEvent::CanVeto}{wxcloseeventcanveto} returns false), the window should always be destroyed, otherwise there is the option to
 ignore the request, or maybe wait until the user has answered a question
-before deciding whether it's safe to close.
+before deciding whether it is safe to close. The handler for EVT\_CLOSE should
+signal to the calling code if it does not destroy the window, by calling 
+\helpref{wxCloseEvent::Veto}{wxcloseeventveto}. Calling this provides useful information
+to the calling code.
 
 The wxCloseEvent handler should only call \helpref{wxWindow::Destroy}{wxwindowdestroy} to
 delete the window, and not use the {\bf delete} operator. This is because
-for some window classes, wxWindows delays actual deletion of the window until all events have been processed,
+for some window classes, wxWidgets delays actual deletion of the window until all events have been processed,
 since otherwise there is the danger that events will be sent to a non-existent window.
 
+As reinforced in the next section, calling Close does not guarantee that the window
+will be destroyed. Call \helpref{wxWindow::Destroy}{wxwindowdestroy} if you want to be
+certain that the window is destroyed.
+
 \wxheading{How can the application close a window itself?}
 
-Your application can use the \helpref{wxWindow::Close}{wxwindowclose} event just as
-the framework does. Pass a TRUE argument to this function to tell the event handler
-that we definitely want to delete the frame.
+Your application can either use \helpref{wxWindow::Close}{wxwindowclose} event just as
+the framework does, or it can call \helpref{wxWindow::Destroy}{wxwindowdestroy} directly.
+If using Close(), you can pass a true argument to this function to tell the event handler
+that we definitely want to delete the frame and it cannot be vetoed.
 
-If for some reason you don't wish to use the {\bf Close} function to delete a window, at least use
-the {\bf Destroy} function so that wxWindows can decide when it's safe to delete the window.
+The advantage of using Close instead of Destroy is that it will call any clean-up code
+defined by the EVT\_CLOSE handler; for example it may close a document contained in
+a window after first asking the user whether the work should be saved. Close can be vetoed
+by this process (return false), whereas Destroy definitely destroys the window.
 
 \wxheading{What is the default behaviour?}
 
-By default, the close event handlers for wxFrame and wxDialog
-both call the old \helpref{wxWindow::OnClose}{wxwindowonclose} handler
-for backward compatibility. So you can still use the old form if you wish.
-
-In addition, the default close event handler for wxDialog simulates a Cancel command,
+The default close event handler for wxDialog simulates a Cancel command,
 generating a wxID\_CANCEL event. Since the handler for this cancel event might
-itself call {\bf Close}, there is a check for infinite looping.
+itself call {\bf Close}, there is a check for infinite looping. The default handler
+for wxID\_CANCEL hides the dialog (if modeless) or calls EndModal(wxID\_CANCEL) (if modal).
+In other words, by default, the dialog {\it is not destroyed} (it might have been created
+on the stack, so the assumption of dynamic creation cannot be made).
 
-Under Windows, wxDialog also defines a handler for \helpref{wxWindow::OnCharHook}{wxwindowoncharhook} that
-generates a Cancel event if the Escape key has been pressed.
+The default close event handler for wxFrame destroys the frame using Destroy().
 
 \wxheading{What should I do when the user calls up Exit from a menu?}
 
@@ -59,13 +67,10 @@ the exit command altogether.
 
 \wxheading{What should I do to upgrade my 1.xx OnClose to 2.0?}
 
-In wxWindows 1.xx, the {\bf OnClose} function did not actually delete 'this', but signalled
-to the calling function (either {\bf Close}, or the wxWindows framework) to delete
+In wxWidgets 1.xx, the {\bf OnClose} function did not actually delete 'this', but signaled
+to the calling function (either {\bf Close}, or the wxWidgets framework) to delete
 or not delete the window.
 
-You can still use this function unchanged in 2.0, but it's worth upgrading to
-the new method in case future versions of wxWindows does not support the old one.
-
 To update your code, you should provide an event table entry in your frame or
 dialog, using the EVT\_CLOSE macro. The event handler function might look like this:
 
@@ -73,22 +78,13 @@ dialog, using the EVT\_CLOSE macro. The event handler function might look like t
 \begin{verbatim}
   void MyFrame::OnCloseWindow(wxCloseEvent& event)
   {
-    // If the application forces the deletion,
-    // obey without question.
-    if (event.GetForce())
-    {
-      this->Destroy();
-      return;
-    }
-
-    // Otherwise...
     if (MyDataHasBeenModified())
     {
       wxMessageDialog* dialog = new wxMessageDialog(this,
         "Save changed data?", "My app", wxYES_NO|wxCANCEL);
 
       int ans = dialog->ShowModal();
-      dialog->Close(TRUE);
+      dialog->Destroy();
 
       switch (ans)
       {
@@ -101,6 +97,10 @@ dialog, using the EVT\_CLOSE macro. The event handler function might look like t
           break;
         case wxID_CANCEL:   // Do nothing - so don't quit app.
         default:
+          if (!event.CanVeto()) // Test if we can veto this deletion
+            this->Destroy();    // If not, destroy the window anyway.
+          else
+            event.Veto();     // Notify the calling code that we didn't delete the frame.
           break;
       }
     }
@@ -110,8 +110,9 @@ dialog, using the EVT\_CLOSE macro. The event handler function might look like t
 
 \wxheading{How do I exit the application gracefully?}
 
-A wxWindows application automatically exits when the designated top window, or the
-last frame or dialog, is destroyed.
+A wxWidgets application automatically exits when the designated top window, or the
+last frame or dialog, is destroyed. Put any application-wide cleanup code in \helpref{wxApp::OnExit}{wxapponexit} (this
+is a virtual function, not an event handler).
 
 \wxheading{Do child windows get deleted automatically?}