]>
Commit | Line | Data |
---|---|---|
a660d684 KB |
1 | \section{Window deletion overview}\label{windowdeletionoverview} |
2 | ||
3 | Classes: \helpref{wxCloseEvent}{wxcloseevent}, \helpref{wxWindow}{wxwindow} | |
4 | ||
5 | Window deletion can be a confusing subject, so this overview is provided | |
6 | to make it clear when and how you delete windows, or respond to user requests | |
7 | to close windows. | |
8 | ||
9 | \wxheading{What is the sequence of events in a window deletion?} | |
10 | ||
11 | When the user clicks on the system close button or system close command, | |
12 | in a frame or a dialog, wxWindows calls \helpref{wxWindow::Close}{wxwindowclose}. | |
13 | ||
14 | This function then generates a \helpref{wxCloseEvent}{wxcloseevent} event which | |
15 | can be handled by the application (by using an EVT\_CLOSE event table entry). It is the duty of the application to | |
16 | define a suitable event handler, and decide whether or not to destroy the window. | |
17 | If the application is for some reason forcing the application to close, | |
18 | the window should always be destroyed, otherwise there is the option to | |
19 | ignore the request, or maybe wait until the user has answered a question | |
20 | before deciding whether it's safe to close. | |
21 | ||
22 | The wxCloseEvent handler should only call \helpref{wxWindow::Destroy}{wxwindowdestroy} to | |
23 | delete the window, and not use the {\bf delete} operator. This is because | |
24 | for some window classes, wxWindows delays actual deletion of the window until all events have been processed, | |
25 | since otherwise there is the danger that events will be sent to a non-existent window. | |
26 | ||
27 | \wxheading{How can the application close a window itself?} | |
28 | ||
29 | Your application can use the \helpref{wxWindow::Close}{wxwindowclose} event just as | |
30 | the framework does. Pass a TRUE argument to this function to tell the event handler | |
31 | that we definitely want to delete the frame. | |
32 | ||
33 | If for some reason you don't wish to use the {\bf Close} function to delete a window, at least use | |
34 | the {\bf Destroy} function so that wxWindows can decide when it's safe to delete the window. | |
35 | ||
36 | \wxheading{What is the default behaviour?} | |
37 | ||
38 | By default, the close event handlers for wxFrame and wxDialog | |
39 | both call the old \helpref{wxWindow::OnClose}{wxwindowonclose} handler | |
40 | for backward compatibility. So you can still use the old form if you wish. | |
41 | ||
42 | In addition, the default close event handler for wxDialog simulates a Cancel command, | |
43 | generating a wxID\_CANCEL event. Since the handler for this cancel event might | |
44 | itself call {\bf Close}, there is a check for infinite looping. | |
45 | ||
46 | Under Windows, wxDialog also defines a handler for \helpref{wxWindow::OnCharHook}{wxwindowoncharhook} that | |
47 | generates a Cancel event if the Escape key has been pressed. | |
48 | ||
49 | \wxheading{What should I do when the user calls up Exit from a menu?} | |
50 | ||
51 | You can simply call \helpref{wxWindow::Close}{wxwindowclose} on the frame. This | |
52 | will invoke your own close event handler which may destroy the frame. | |
53 | ||
54 | You can do checking to see if your application can be safely exited at this point, | |
55 | either from within your close event handler, or from within your exit menu command | |
56 | handler. For example, you may wish to check that all files have been saved. | |
57 | Give the user a chance to save and quit, to not save but quit anyway, or to cancel | |
58 | the exit command altogether. | |
59 | ||
60 | \wxheading{What should I do to upgrade my 1.xx OnClose to 2.0?} | |
61 | ||
62 | In wxWindows 1.xx, the {\bf OnClose} function did not actually delete 'this', but signalled | |
63 | to the calling function (either {\bf Close}, or the wxWindows framework) to delete | |
64 | or not delete the window. | |
65 | ||
66 | You can still use this function unchanged in 2.0, but it's worth upgrading to | |
67 | the new method in case future versions of wxWindows does not support the old one. | |
68 | ||
69 | To update your code, you should provide an event table entry in your frame or | |
70 | dialog, using the EVT\_CLOSE macro. The event handler function might look like this: | |
71 | ||
72 | {\small% | |
73 | \begin{verbatim} | |
74 | void MyFrame::OnCloseWindow(wxCloseEvent& event) | |
75 | { | |
76 | // If the application forces the deletion, | |
77 | // obey without question. | |
78 | if (event.GetForce()) | |
79 | { | |
80 | this->Destroy(); | |
81 | return; | |
82 | } | |
83 | ||
84 | // Otherwise... | |
85 | if (MyDataHasBeenModified()) | |
86 | { | |
87 | wxMessageDialog* dialog = new wxMessageDialog(this, | |
88 | "Save changed data?", "My app", wxYES_NO|wxCANCEL); | |
89 | ||
90 | int ans = dialog->ShowModal(); | |
91 | dialog->Close(TRUE); | |
92 | ||
93 | switch (ans) | |
94 | { | |
95 | case wxID_YES: // Save, then destroy, quitting app | |
96 | SaveMyData(); | |
97 | this->Destroy(); | |
98 | break; | |
99 | case wxID_NO: // Don't save; just destroy, quitting app | |
100 | this->Destroy(); | |
101 | break; | |
102 | case wxID_CANCEL: // Do nothing - so don't quit app. | |
103 | default: | |
104 | break; | |
105 | } | |
106 | } | |
107 | } | |
108 | \end{verbatim} | |
109 | }% | |
110 | ||
111 | \wxheading{How do I exit the application gracefully?} | |
112 | ||
113 | A wxWindows application automatically exits when the top frame (returned | |
114 | from \helpref{wxApp::OnInit}{wxapponinit}) is destroyed. This may be modified | |
115 | in later versions to exit only when the {\it last} top-level frame is destroyed. | |
116 | ||
117 | \wxheading{Do child windows get deleted automatically?} | |
118 | ||
119 | Yes, child windows are deleted from within the parent destructor. This includes any children | |
120 | that are themselves frames or dialogs, so you may wish to close these child frame or dialog windows | |
121 | explicitly from within the parent close handler. | |
122 | ||
123 | \wxheading{What about other kinds of window?} | |
124 | ||
125 | So far we've been talking about `managed' windows, i.e. frames and dialogs. Windows | |
126 | with parents, such as controls, don't have delayed destruction and don't usually have | |
127 | close event handlers, though you can implement them if you wish. For consistency, | |
128 | continue to use the \helpref{wxWindow::Destroy}{wxwindowdestroy} function instead | |
129 | of the {\bf delete} operator when deleting these kinds of windows explicitly. | |
130 |