git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			131 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
| \section{Window deletion overview}\label{windowdeletionoverview}
 | |
| 
 | |
| 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 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}.
 | |
| 
 | |
| 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
 | |
| ignore the request, or maybe wait until the user has answered a question
 | |
| before deciding whether it's safe to close.
 | |
| 
 | |
| 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,
 | |
| since otherwise there is the danger that events will be sent to a non-existent window.
 | |
| 
 | |
| \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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| \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,
 | |
| generating a wxID\_CANCEL event. Since the handler for this cancel event might
 | |
| itself call {\bf Close}, there is a check for infinite looping.
 | |
| 
 | |
| Under Windows, wxDialog also defines a handler for \helpref{wxWindow::OnCharHook}{wxwindowoncharhook} that
 | |
| generates a Cancel event if the Escape key has been pressed.
 | |
| 
 | |
| \wxheading{What should I do when the user calls up Exit from a menu?}
 | |
| 
 | |
| You can simply call \helpref{wxWindow::Close}{wxwindowclose} on the frame. This
 | |
| will invoke your own close event handler which may destroy the frame.
 | |
| 
 | |
| You can do checking to see if your application can be safely exited at this point,
 | |
| either from within your close event handler, or from within your exit menu command
 | |
| handler. For example, you may wish to check that all files have been saved.
 | |
| Give the user a chance to save and quit, to not save but quit anyway, or to cancel
 | |
| 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
 | |
| 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:
 | |
| 
 | |
| {\small%
 | |
| \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);
 | |
| 
 | |
|       switch (ans)
 | |
|       {
 | |
|         case wxID_YES:      // Save, then destroy, quitting app
 | |
|           SaveMyData();
 | |
|           this->Destroy();
 | |
|           break;
 | |
|         case wxID_NO:       // Don't save; just destroy, quitting app
 | |
|           this->Destroy();
 | |
|           break;
 | |
|         case wxID_CANCEL:   // Do nothing - so don't quit app.
 | |
|         default:
 | |
|           break;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| \end{verbatim}
 | |
| }%
 | |
| 
 | |
| \wxheading{How do I exit the application gracefully?}
 | |
| 
 | |
| A wxWindows application automatically exits when the top frame (returned
 | |
| from \helpref{wxApp::OnInit}{wxapponinit}) is destroyed. This may be modified
 | |
| in later versions to exit only when the {\it last} top-level frame is destroyed.
 | |
| 
 | |
| \wxheading{Do child windows get deleted automatically?}
 | |
| 
 | |
| Yes, child windows are deleted from within the parent destructor. This includes any children
 | |
| that are themselves frames or dialogs, so you may wish to close these child frame or dialog windows
 | |
| explicitly from within the parent close handler.
 | |
| 
 | |
| \wxheading{What about other kinds of window?}
 | |
| 
 | |
| So far we've been talking about `managed' windows, i.e. frames and dialogs. Windows
 | |
| with parents, such as controls, don't have delayed destruction and don't usually have
 | |
| close event handlers, though you can implement them if you wish. For consistency,
 | |
| continue to use the \helpref{wxWindow::Destroy}{wxwindowdestroy} function instead
 | |
| of the {\bf delete} operator when deleting these kinds of windows explicitly.
 | |
| 
 |