destroy the frame if the exception occurs in a dialog shown from it
[wxWidgets.git] / samples / except / except.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: except.cpp
3 // Purpose: Except wxWindows sample
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWindows headers)
29 #ifndef WX_PRECOMP
30 #include "wx/log.h"
31
32 #include "wx/app.h"
33 #include "wx/frame.h"
34 #include "wx/dialog.h"
35 #include "wx/menu.h"
36
37 #include "wx/button.h"
38 #include "wx/sizer.h"
39
40 #include "wx/utils.h" // for wxMessageBox
41 #endif
42
43 // ----------------------------------------------------------------------------
44 // resources
45 // ----------------------------------------------------------------------------
46
47 // the application icon (under Windows and OS/2 it is in resources)
48 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
49 #include "../sample.xpm"
50 #endif
51
52 // ----------------------------------------------------------------------------
53 // private classes
54 // ----------------------------------------------------------------------------
55
56 // Define a new application type, each program should derive a class from wxApp
57 class MyApp : public wxApp
58 {
59 public:
60 // override base class virtuals
61 // ----------------------------
62
63 // program startup
64 virtual bool OnInit();
65
66 // 2nd-level exception handling: we get all the exceptions occuring in any
67 // event handler here
68 virtual void HandleEvent(wxEvtHandler *handler,
69 wxEventFunction func,
70 wxEvent& event) const;
71
72 // 3rd, and final, level exception handling: whenever an unhandled
73 // exception is caught, this function is called
74 virtual void OnUnhandledException();
75 };
76
77 // Define a new frame type: this is going to be our main frame
78 class MyFrame : public wxFrame
79 {
80 public:
81 // ctor(s)
82 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
83 long style = wxDEFAULT_FRAME_STYLE);
84
85 // event handlers (these functions should _not_ be virtual)
86 void OnQuit(wxCommandEvent& event);
87 void OnAbout(wxCommandEvent& event);
88 void OnDialog(wxCommandEvent& event);
89 void OnThrowString(wxCommandEvent& event);
90
91 // 1st-level exception handling: we overload ProcessEvent() to be able to
92 // catch exceptions which occur in MyFrame methods here
93 virtual bool ProcessEvent(wxEvent& event);
94
95 private:
96 // any class wishing to process wxWindows events must use this macro
97 DECLARE_EVENT_TABLE()
98 };
99
100 // A simple dialog which has only some buttons to throw exceptions
101 class MyDialog : public wxDialog
102 {
103 public:
104 MyDialog(wxFrame *parent);
105
106 // event handlers
107 void OnThrowInt(wxCommandEvent& event);
108 void OnThrowObject(wxCommandEvent& event);
109
110 private:
111 DECLARE_EVENT_TABLE()
112 };
113
114 // A trivial exception class
115 class MyException
116 {
117 public:
118 MyException(const wxString& msg) : m_msg(msg) { }
119
120 const wxChar *what() const { return m_msg.c_str(); }
121
122 private:
123 wxString m_msg;
124 };
125
126 // ----------------------------------------------------------------------------
127 // constants
128 // ----------------------------------------------------------------------------
129
130 // IDs for the controls and the menu commands
131 enum
132 {
133 // control ids
134 Except_ThrowInt = 100,
135 Except_ThrowObject,
136
137 // menu items
138 Except_ThrowString = 200,
139 Except_Dialog,
140
141 Except_Quit = wxID_EXIT,
142 Except_About = wxID_ABOUT
143 };
144
145 // ----------------------------------------------------------------------------
146 // event tables and other macros for wxWindows
147 // ----------------------------------------------------------------------------
148
149 // the event tables connect the wxWindows events with the functions (event
150 // handlers) which process them. It can be also done at run-time, but for the
151 // simple menu events like this the static method is much simpler.
152 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
153 EVT_MENU(Except_Quit, MyFrame::OnQuit)
154 EVT_MENU(Except_About, MyFrame::OnAbout)
155 EVT_MENU(Except_Dialog, MyFrame::OnDialog)
156 EVT_MENU(Except_ThrowString, MyFrame::OnThrowString)
157 END_EVENT_TABLE()
158
159 BEGIN_EVENT_TABLE(MyDialog, wxDialog)
160 EVT_BUTTON(Except_ThrowInt, MyDialog::OnThrowInt)
161 EVT_BUTTON(Except_ThrowObject, MyDialog::OnThrowObject)
162 END_EVENT_TABLE()
163
164 // Create a new application object: this macro will allow wxWindows to create
165 // the application object during program execution (it's better than using a
166 // static object for many reasons) and also implements the accessor function
167 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
168 // not wxApp)
169 IMPLEMENT_APP(MyApp)
170
171 // ============================================================================
172 // MyApp implementation
173 // ============================================================================
174
175 // 'Main program' equivalent: the program execution "starts" here
176 bool MyApp::OnInit()
177 {
178 // create the main application window
179 MyFrame *frame = new MyFrame(_T("Except wxWindows App"),
180 wxPoint(50, 50), wxSize(450, 340));
181
182 // and show it (the frames, unlike simple controls, are not shown when
183 // created initially)
184 frame->Show(true);
185
186 // success: wxApp::OnRun() will be called which will enter the main message
187 // loop and the application will run. If we returned false here, the
188 // application would exit immediately.
189 return true;
190 }
191
192 void
193 MyApp::HandleEvent(wxEvtHandler *handler,
194 wxEventFunction func,
195 wxEvent& event) const
196 {
197 try
198 {
199 wxApp::HandleEvent(handler, func, event);
200 }
201 catch ( int i )
202 {
203 wxLogError(_T("Caught an int %d in MyApp."), i);
204 }
205 }
206
207 void MyApp::OnUnhandledException()
208 {
209 wxMessageBox(_T("Unhandled exception caught, program will terminate."),
210 _T("wxExcept Sample"), wxOK | wxICON_ERROR);
211 }
212
213 // ============================================================================
214 // MyFrame implementation
215 // ============================================================================
216
217 // frame constructor
218 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
219 : wxFrame(NULL, -1, title, pos, size, style)
220 {
221 // set the frame icon
222 SetIcon(wxICON(mondrian));
223
224 #if wxUSE_MENUS
225 // create a menu bar
226 wxMenu *menuFile = new wxMenu;
227 menuFile->Append(Except_Dialog, _T("Show &dialog\tCtrl-D"));
228 menuFile->Append(Except_ThrowString, _T("Throw a &string\tCtrl-S"));
229 menuFile->AppendSeparator();
230 menuFile->Append(Except_Quit, _T("E&xit\tCtrl-Q"), _T("Quit this program"));
231
232 wxMenu *helpMenu = new wxMenu;
233 helpMenu->Append(Except_About, _T("&About...\tF1"), _T("Show about dialog"));
234
235 // now append the freshly created menu to the menu bar...
236 wxMenuBar *menuBar = new wxMenuBar();
237 menuBar->Append(menuFile, _T("&File"));
238 menuBar->Append(helpMenu, _T("&Help"));
239
240 // ... and attach this menu bar to the frame
241 SetMenuBar(menuBar);
242 #endif // wxUSE_MENUS
243
244 #if wxUSE_STATUSBAR && !defined(__WXWINCE__)
245 // create a status bar just for fun (by default with 1 pane only)
246 CreateStatusBar(2);
247 SetStatusText(_T("Welcome to wxWindows!"));
248 #endif // wxUSE_STATUSBAR
249 }
250
251 bool MyFrame::ProcessEvent(wxEvent& event)
252 {
253 try
254 {
255 return wxFrame::ProcessEvent(event);
256 }
257 catch ( const wxChar *msg )
258 {
259 wxLogMessage(_T("Caught a string \"%s\" in MyFrame"), msg);
260
261 return true;
262 }
263 }
264
265 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
266 {
267 // true is to force the frame to close
268 Close(true);
269 }
270
271 void MyFrame::OnDialog(wxCommandEvent& WXUNUSED(event))
272 {
273 try
274 {
275 MyDialog dlg(this);
276
277 dlg.ShowModal();
278 }
279 catch ( ... )
280 {
281 Destroy();
282 throw;
283 }
284 }
285
286 void MyFrame::OnThrowString(wxCommandEvent& WXUNUSED(event))
287 {
288 throw _T("some string");
289 }
290
291 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
292 {
293 wxString msg;
294 msg.Printf( _T("This is the About dialog of the except sample.\n")
295 _T("Welcome to %s"), wxVERSION_STRING);
296
297 wxMessageBox(msg, _T("About Except"), wxOK | wxICON_INFORMATION, this);
298 }
299
300 // ============================================================================
301 // MyDialog implementation
302 // ============================================================================
303
304 MyDialog::MyDialog(wxFrame *parent)
305 : wxDialog(parent, -1, wxString(_T("Throw exception dialog")))
306 {
307 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
308
309 sizerTop->Add(new wxButton(this, Except_ThrowInt, _T("Throw &int")),
310 0, wxCENTRE | wxALL, 5);
311 sizerTop->Add(new wxButton(this, Except_ThrowObject, _T("Throw &object")),
312 0, wxCENTRE | wxALL, 5);
313 sizerTop->Add(new wxButton(this, wxID_CANCEL, _T("&Cancel")),
314 0, wxCENTRE | wxALL, 5);
315
316 SetSizer(sizerTop);
317 sizerTop->Fit(this);
318 }
319
320 void MyDialog::OnThrowInt(wxCommandEvent& WXUNUSED(event))
321 {
322 throw 17;
323 }
324
325 void MyDialog::OnThrowObject(wxCommandEvent& WXUNUSED(event))
326 {
327 throw MyException(_T("Exception thrown from the dialog"));
328 }
329