]> git.saurik.com Git - wxWidgets.git/blame - samples/xti/xti.cpp
Fix a crash in wxExecute() in wxMSW too.
[wxWidgets.git] / samples / xti / xti.cpp
CommitLineData
cc3977bf
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: xti.cpp
3// Purpose: eXtended RTTI support sample
4// Author: Stefan Csomor, Francesco Montorsi
5// Modified by:
6// Created: 13/5/2007
e1d3601a 7// RCS-ID: $Id$
cc3977bf
SC
8// Copyright: (c) Stefan Csomor, Francesco Montorsi
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" wxWidgets headers)
29#ifndef WX_PRECOMP
30 #include "wx/wx.h"
31#endif
32
33#include "wx/wx.h"
34#include "wx/variant.h"
35#include "wx/xml/xml.h"
36#include "wx/frame.h"
37#include "wx/notebook.h"
38#include "wx/event.h"
39#include "wx/spinbutt.h"
40#include "wx/spinctrl.h"
41
42#include "wx/xtistrm.h"
43#include "wx/xtixml.h"
44#include "wx/txtstrm.h"
45#include "wx/wfstream.h"
46#include "wx/sstream.h"
47#include "wx/spinctrl.h"
48
49#include "classlist.h"
50#include "codereadercallback.h"
51
52#if !wxUSE_EXTENDED_RTTI
53 #error This sample requires XTI (eXtended RTTI) enabled
54#endif
55
56
57// ----------------------------------------------------------------------------
58// resources
59// ----------------------------------------------------------------------------
60
e7092398 61#ifndef wxHAS_IMAGES_IN_RESOURCES
cc3977bf
SC
62 #include "../sample.xpm"
63#endif
64
65// ----------------------------------------------------------------------------
66// private classes
67// ----------------------------------------------------------------------------
68
69// Define a new application type, each program should derive a class from wxApp
70class MyApp : public wxApp
71{
72public:
73 virtual bool OnInit();
74};
75
76// Define a new frame type: this is going to be our main frame
77class MyFrame : public wxFrame
78{
79public:
80 // ctor(s)
81 MyFrame(const wxString& title);
82
83 void OnPersist(wxCommandEvent& event);
84 void OnDepersist(wxCommandEvent& event);
85 void OnGenerateCode(wxCommandEvent& event);
86 void OnDumpClasses(wxCommandEvent& event);
87 void OnQuit(wxCommandEvent& event);
88 void OnAbout(wxCommandEvent& event);
89
90private:
91 // any class wishing to process wxWidgets events must use this macro
1bf29304 92 wxDECLARE_EVENT_TABLE();
cc3977bf
SC
93};
94
95// ----------------------------------------------------------------------------
96// constants
97// ----------------------------------------------------------------------------
98
99// IDs for the controls and the menu commands
100enum
101{
102 // menu items
103 Minimal_Persist = wxID_HIGHEST,
104 Minimal_Depersist,
105 Minimal_GenerateCode,
106 Minimal_DumpClasses,
107 Minimal_Quit = wxID_EXIT,
108 Minimal_About = wxID_ABOUT
109};
110
111// ----------------------------------------------------------------------------
112// event tables and other macros for wxWidgets
113// ----------------------------------------------------------------------------
114
115BEGIN_EVENT_TABLE(MyFrame, wxFrame)
116 EVT_MENU(Minimal_Persist, MyFrame::OnPersist)
117 EVT_MENU(Minimal_Depersist, MyFrame::OnDepersist)
118 EVT_MENU(Minimal_GenerateCode, MyFrame::OnGenerateCode)
119 EVT_MENU(Minimal_DumpClasses, MyFrame::OnDumpClasses)
120 EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
121 EVT_MENU(Minimal_About, MyFrame::OnAbout)
122END_EVENT_TABLE()
123
1bf29304 124wxIMPLEMENT_APP(MyApp);
cc3977bf
SC
125
126// ============================================================================
127// implementation
128// ============================================================================
129
130void RegisterFrameRTTI();
131
132// ----------------------------------------------------------------------------
133// the application class
134// ----------------------------------------------------------------------------
135
136bool MyApp::OnInit()
137{
138 if ( !wxApp::OnInit() )
139 return false;
140
141 RegisterFrameRTTI();
142
143 // create the main application window
ebfe373e 144 MyFrame *frame = new MyFrame(wxT("Extended RTTI sample"));
cc3977bf
SC
145
146 // and show it (the frames, unlike simple controls, are not shown when
147 // created initially)
148 frame->Show(true);
149
150 // success: wxApp::OnRun() will be called which will enter the main message
151 // loop and the application will run. If we returned false here, the
152 // application would exit immediately.
153 return true;
154}
155
156// ----------------------------------------------------------------------------
157// main frame
158// ----------------------------------------------------------------------------
159
160MyFrame::MyFrame(const wxString& title)
161 : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
162{
163 // set the frame icon
164 SetIcon(wxICON(sample));
165
166#if wxUSE_MENUS
167 // create a menu bar
168 wxMenu *fileMenu = new wxMenu;
169
170 // the "About" item should be in the help menu
171 wxMenu *helpMenu = new wxMenu;
2d143b66 172 helpMenu->Append(Minimal_About, wxT("&About\tF1"), wxT("Show about dialog"));
ebfe373e
DS
173
174 fileMenu->Append(Minimal_Persist, wxT("Persist a wxFrame to XML..."),
175 wxT("Creates a wxFrame using wxXTI and saves its description as XML"));
176 fileMenu->Append(Minimal_Depersist, wxT("Depersist XML file..."),
177 wxT("Loads the description of wxFrame from XML"));
178 fileMenu->Append(Minimal_GenerateCode, wxT("Generate code for a wxFrame saved to XML..."),
179 wxT("Generates the C++ code which belong to a persisted wxFrame"));
cc3977bf 180 fileMenu->AppendSeparator();
ebfe373e
DS
181 fileMenu->Append(Minimal_DumpClasses, wxT("Dump registered classes..."),
182 wxT("Dumps the description of all wxWidgets classes registered in XTI"));
cc3977bf 183 fileMenu->AppendSeparator();
ebfe373e 184 fileMenu->Append(Minimal_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
cc3977bf
SC
185
186 // now append the freshly created menu to the menu bar...
187 wxMenuBar *menuBar = new wxMenuBar();
ebfe373e
DS
188 menuBar->Append(fileMenu, wxT("&File"));
189 menuBar->Append(helpMenu, wxT("&Help"));
cc3977bf
SC
190
191 // ... and attach this menu bar to the frame
192 SetMenuBar(menuBar);
193#endif // wxUSE_MENUS
194
195#if wxUSE_STATUSBAR
196 // create a status bar just for fun (by default with 1 pane only)
197 CreateStatusBar(2);
ebfe373e 198 SetStatusText(wxT("Welcome to wxWidgets!"));
cc3977bf
SC
199#endif // wxUSE_STATUSBAR
200}
201
202
203
204// ----------------------------------------------------------------------------
205// XTI sample code
206// ----------------------------------------------------------------------------
207
208// this is the kind of source code that would end up being generated by a
209// designer corresponding to the information we are setting up via RTTI
210// in the CreateFrameRTTI function:
211//
212// class MyXTIFrame : public wxFrame
213// {
214// public:
215// // construction
216// MyXTIFrame()
217// {
218// Init();
219// m_button = NULL;
220// }
221//
222// bool Create(wxWindow *parent,
223// wxWindowID id,
224// const wxString& title,
225// const wxPoint& pos = wxDefaultPosition,
226// const wxSize& size = wxDefaultSize,
227// long style = wxDEFAULT_FRAME_STYLE,
228// const wxString& name = wxFrameNameStr)
229// {
230// return wxFrame::Create( parent, id, title, pos, size, style, name );
231// }
232//
233// void SetButton( wxButton * button ) { m_button = button; }
234// wxButton* GetButton() const { return m_button; }
235//
236// void ButtonClickHandler( wxEvent & WXUNUSED(event) )
237// {
238// wxMessageBox( "Button Clicked ", "Hi!", wxOK );
239// }
240//
241// protected:
242// wxButton* m_button;
243//
244// DECLARE_EVENT_TABLE()
245// DECLARE_DYNAMIC_CLASS_NO_COPY(MyXTIFrame)
246// };
247//
248// IMPLEMENT_DYNAMIC_CLASS_XTI(MyXTIFrame, MyXTIFrame, "x.h")
249//
250// WX_BEGIN_PROPERTIES_TABLE(MyXTIFrame)
251// WX_PROPERTY( Button, wxButton*, SetButton, GetButton, )
252// WX_END_PROPERTIES_TABLE()
253//
254// WX_BEGIN_HANDLERS_TABLE(MyXTIFrame)
255// WX_HANDLER( ButtonClickHandler, wxCommandEvent )
256// WX_END_HANDLERS_TABLE()
257//
258// WX_CONSTRUCTOR_5( MyXTIFrame, wxWindow*, Parent, wxWindowID, Id,
259// wxString, Title, wxPoint, Position, wxSize, Size )
260//
261// BEGIN_EVENT_TABLE(MyXTIFrame, wxFrame)
262// END_EVENT_TABLE()
263
264// the following class "persists" (i.e. saves) a wxFrame into a wxObjectWriter
265
1bf29304 266class MyDesignerPersister : public wxObjectWriterCallback
cc3977bf
SC
267{
268public:
269 MyDesignerPersister( wxDynamicObject * frame)
270 {
271 m_frame = frame;
272 }
273
274 virtual bool BeforeWriteDelegate( wxObjectWriter *WXUNUSED(writer),
275 const wxObject *object,
276 const wxClassInfo* WXUNUSED(classInfo),
277 const wxPropertyInfo *propInfo,
278 const wxObject *&eventSink,
279 const wxHandlerInfo* &handlerInfo )
280 {
1bf29304 281 // this approach would be used if the handler would not
cc3977bf
SC
282 // be connected really in the designer, so we have to supply
283 // the information
1bf29304
SC
284 const wxObject* but = wxAnyGetAsObjectPtr( m_frame->GetProperty(wxT("Button")) );
285 if ( object == but &&
286 propInfo == wxCLASSINFO( wxButton )->FindPropertyInfo(wxT("OnClick")) )
cc3977bf
SC
287 {
288 eventSink = m_frame;
289 handlerInfo = m_frame->GetClassInfo()->
1bf29304 290 FindHandlerInfo(wxT("ButtonClickHandler"));
cc3977bf
SC
291 return true;
292 }
293 return false;
294 }
295
296private:
297 wxDynamicObject *m_frame;
298};
299
300// sometimes linkers (at least MSVC and GCC ones) optimize the final EXE
301// even in debug mode pruning the object files which he "thinks" are useless;
302// thus the classes defined in those files won't be available in the XTI
303// table and the program will fail to allocate them.
304// The following macro implements a simple hack to ensure that a given
305// class is linked in.
306//
307// TODO: in wx/link.h there are already similar macros (also more "optimized":
308// don't need the creation of fake object) which however require to use
309// the wxFORCE_LINK_THIS_MODULE() macro inside the source files corresponding
310// to the class being discarded.
311//
312#define wxENSURE_CLASS_IS_LINKED(x) { x test; }
313
314void RegisterFrameRTTI()
315{
316 // set up the RTTI info for a class (MyXTIFrame) which
317 // is not defined anywhere in this program
318 wxDynamicClassInfo *dyninfo =
319 wx_dynamic_cast( wxDynamicClassInfo *, wxClassInfo::FindClass(wxT("MyXTIFrame")));
320 if ( dyninfo == NULL )
321 {
322 dyninfo = new wxDynamicClassInfo(wxT("myxtiframe.h"),
323 wxT("MyXTIFrame"),
324 CLASSINFO(wxFrame) );
325
326 // this class has a property named "Button" and the relative handler:
1bf29304
SC
327 dyninfo->AddProperty(wxT("Button"), wxGetTypeInfo((wxButton**) NULL));
328 dyninfo->AddHandler(wxT("ButtonClickHandler"),
cc3977bf
SC
329 NULL /* no instance of the handler method */, CLASSINFO( wxEvent ) );
330 }
331}
332
333wxDynamicObject* CreateFrameRTTI()
334{
335 int baseID = 100;
1bf29304 336 wxAny Params[10];
cc3977bf
SC
337
338 // the class is now part of XTI internal table so that we can
339 // get a pointer to it just searching it like any other class:
340 wxFrame* frame;
341 wxClassInfo *info = wxClassInfo::FindClass(wxT("MyXTIFrame"));
342 wxASSERT( info );
343 wxDynamicObject* frameWrapper =
344 wx_dynamic_cast(wxDynamicObject*, info->CreateObject() );
1bf29304
SC
345 Params[0] = wxAny((wxWindow*)(NULL));
346 Params[1] = wxAny(wxWindowID(baseID++));
347 Params[2] = wxAny(wxString(wxT("This is a frame created from XTI")));
348 Params[3] = wxAny(wxPoint(-1,-1));
349 Params[4] = wxAny(wxSize(400,300));
350 Params[5] = wxAny((long)wxDEFAULT_FRAME_STYLE);
cc3977bf
SC
351 wxASSERT( info->Create(frameWrapper, 6, Params ));
352 frame = wx_dynamic_cast(wxFrame*, frameWrapper->GetSuperClassInstance());
353
1bf29304 354#if 1
cc3977bf
SC
355 // now build a notebook inside it:
356 wxNotebook* notebook;
357 info = wxClassInfo::FindClass("wxNotebook");
358 wxASSERT( info );
359 notebook = wxDynamicCast( info->CreateObject(), wxNotebook );
1bf29304
SC
360 Params[0] = wxAny((wxWindow*)frame);
361 Params[1] = wxAny(wxWindowID(baseID++));
362 Params[2] = wxAny(wxPoint( 10, 10 ));
363 Params[3] = wxAny(wxDefaultSize);
364 Params[4] = wxAny((long)0);
cc3977bf
SC
365 wxASSERT( info->Create(notebook, 5, Params ));
366
367 // button page
368
369 wxPanel* panel;
370 info = wxClassInfo::FindClass("wxPanel");
371 wxASSERT( info );
372 panel = wxDynamicCast( info->CreateObject(), wxPanel );
1bf29304
SC
373 Params[0] = wxAny((wxWindow*)(notebook));
374 Params[1] = wxAny(wxWindowID(baseID++));
375 Params[2] = wxAny(wxPoint(-1,-1));
376 Params[3] = wxAny(wxSize(-1,-1));
377 Params[4] = wxAny((long)0);
378 Params[5] = wxAny(wxString(wxT("Hello")));
cc3977bf
SC
379 wxASSERT( info->Create(panel, 6, Params ));
380 notebook->AddPage( panel, "Buttons" );
381
382 wxButton* button;
383 info = wxClassInfo::FindClass("wxButton");
384 wxASSERT( info );
385 button = wxDynamicCast( info->CreateObject(), wxButton );
1bf29304
SC
386 Params[0] = wxAny((wxWindow*)(panel));
387 Params[1] = wxAny(wxWindowID(baseID++));
388 Params[2] = wxAny(wxString(wxT("Click Me!")));
389 Params[3] = wxAny(wxPoint( 10, 10 ));
390 Params[4] = wxAny(wxSize(-1,-1));
391 Params[5] = wxAny((long)0);
cc3977bf 392 wxASSERT( info->Create(button, 6, Params ));
1bf29304 393 frameWrapper->SetProperty( wxT("Button"), wxAny( button ) );
cc3977bf
SC
394
395 // other controls page
396
397 info = wxClassInfo::FindClass("wxPanel");
398 wxASSERT( info );
399 panel = wxDynamicCast( info->CreateObject(), wxPanel );
1bf29304
SC
400 Params[0] = wxAny((wxWindow*)(notebook));
401 Params[1] = wxAny(wxWindowID(baseID++));
402 Params[2] = wxAny(wxPoint(-1,-1));
403 Params[3] = wxAny(wxSize(-1,-1));
404 Params[4] = wxAny((long)0);
405 Params[5] = wxAny(wxString(wxT("Hello")));
cc3977bf
SC
406 wxASSERT( info->Create(panel, 6, Params ));
407 notebook->AddPage( panel, "Other Standard controls" );
408
409 wxControl* control;
410 info = wxClassInfo::FindClass("wxCheckBox");
411 wxASSERT( info );
412 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
413 Params[0] = wxAny((wxWindow*)(panel));
414 Params[1] = wxAny(wxWindowID(baseID++));
415 Params[2] = wxAny(wxString(wxT("A Checkbox")));
416 Params[3] = wxAny(wxPoint( 10, 10 ));
417 Params[4] = wxAny(wxSize(-1,-1));
418 Params[5] = wxAny((long)0);
cc3977bf
SC
419 wxASSERT( info->Create(control, 6, Params ));
420
421 info = wxClassInfo::FindClass("wxRadioButton");
422 wxASSERT( info );
423 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
424 Params[0] = wxAny((wxWindow*)(panel));
425 Params[1] = wxAny(wxWindowID(baseID++));
426 Params[2] = wxAny(wxString(wxT("A Radiobutton")));
427 Params[3] = wxAny(wxPoint( 10, 30 ));
428 Params[4] = wxAny(wxSize(-1,-1));
429 Params[5] = wxAny((long)0);
cc3977bf
SC
430 wxASSERT( info->Create(control, 6, Params ));
431
432 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
433 Params[1] = wxAny(wxWindowID(baseID++));
434 Params[2] = wxAny(wxString(wxT("Another One")));
435 Params[3] = wxAny(wxPoint( 10, 50 ));
cc3977bf
SC
436 wxASSERT( info->Create(control, 6, Params ));
437
438 info = wxClassInfo::FindClass("wxStaticText");
439 wxASSERT( info );
440 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
441 Params[0] = wxAny((wxWindow*)(panel));
442 Params[1] = wxAny(wxWindowID(baseID++));
443 Params[2] = wxAny(wxString(wxT("A Static Text!")));
444 Params[3] = wxAny(wxPoint( 10, 70 ));
445 Params[4] = wxAny(wxSize(-1,-1));
446 Params[5] = wxAny((long)0);
cc3977bf
SC
447 wxASSERT( info->Create(control, 6, Params ));
448
449 info = wxClassInfo::FindClass("wxStaticBox");
450 wxASSERT( info );
451 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
452 Params[0] = wxAny((wxWindow*)(panel));
453 Params[1] = wxAny(wxWindowID(baseID++));
454 Params[2] = wxAny(wxString(wxT("A Static Box")));
455 Params[3] = wxAny(wxPoint( 10, 90 ));
456 Params[4] = wxAny(wxSize(100,80));
457 Params[5] = wxAny((long)0);
cc3977bf
SC
458 wxASSERT( info->Create(control, 6, Params ));
459
460 info = wxClassInfo::FindClass("wxTextCtrl");
461 wxASSERT( info );
462 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
463 Params[0] = wxAny((wxWindow*)(panel));
464 Params[1] = wxAny(wxWindowID(baseID++));
465 Params[2] = wxAny(wxString(wxT("A Text Control")));
466 Params[3] = wxAny(wxPoint( 10, 200 ));
467 Params[4] = wxAny(wxSize(-1,-1));
468 Params[5] = wxAny((long)0);
cc3977bf
SC
469 wxASSERT( info->Create(control, 6, Params ));
470
471 // spins and gauges page
472
473 info = wxClassInfo::FindClass("wxPanel");
474 wxASSERT( info );
475 panel = wxDynamicCast( info->CreateObject(), wxPanel );
1bf29304
SC
476 Params[0] = wxAny((wxWindow*)(notebook));
477 Params[1] = wxAny(wxWindowID(baseID++));
478 Params[2] = wxAny(wxPoint(-1,-1));
479 Params[3] = wxAny(wxSize(-1,-1));
480 Params[4] = wxAny((long)0);
481 Params[5] = wxAny(wxString(wxT("Hello")));
cc3977bf
SC
482 wxASSERT( info->Create(panel, 6, Params ));
483 notebook->AddPage( panel, "Spins and Sliders" );
484
485 wxENSURE_CLASS_IS_LINKED(wxSpinButton);
486
487 info = wxClassInfo::FindClass("wxSpinButton");
488 wxASSERT( info );
489 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
490 Params[0] = wxAny((wxWindow*)(panel));
491 Params[1] = wxAny(wxWindowID(baseID++));
492 Params[2] = wxAny(wxPoint( 10, 10 ));
493 Params[3] = wxAny(wxSize(-1,-1));
494 Params[4] = wxAny((long)wxSP_VERTICAL | wxSP_ARROW_KEYS);
cc3977bf
SC
495 wxASSERT( info->Create(control, 5, Params ));
496
497 wxENSURE_CLASS_IS_LINKED(wxSpinCtrl);
498
499 info = wxClassInfo::FindClass("wxSpinCtrl");
500 wxASSERT( info );
501 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
502 Params[0] = wxAny((wxWindow*)(panel));
503 Params[1] = wxAny(wxWindowID(baseID++));
504 Params[2] = wxAny(wxString("20"));
505 Params[3] = wxAny(wxPoint( 40, 10 ));
506 Params[4] = wxAny(wxSize(40,-1));
507 Params[5] = wxAny((long) wxSP_ARROW_KEYS);
cc3977bf
SC
508 wxASSERT( info->Create(control, 6, Params ));
509
510 // MSVC likes to exclude from link wxGauge...
511 wxENSURE_CLASS_IS_LINKED(wxGauge)
512 wxENSURE_CLASS_IS_LINKED(wxCheckBox)
513 wxENSURE_CLASS_IS_LINKED(wxSpinCtrl)
514
cc3977bf 515 info = wxClassInfo::FindClass("wxGauge");
1bf29304 516
cc3977bf
SC
517 wxASSERT( info );
518 control = wxDynamicCast( info->CreateObject(), wxControl );
1bf29304
SC
519 Params[0] = wxAny((wxWindow*)(panel));
520 Params[1] = wxAny(wxWindowID(baseID++));
521 Params[2] = wxAny((int) 100);
522 Params[3] = wxAny(wxPoint( 10, 50 ));
523 Params[4] = wxAny(wxSize(-1,-1));
524 Params[5] = wxAny((long) wxGA_HORIZONTAL);
cc3977bf
SC
525 wxASSERT( info->Create(control, 6, Params ));
526 wx_dynamic_cast(wxGauge*, control)->SetValue(20);
527
1bf29304 528#endif
cc3977bf
SC
529 return frameWrapper;
530}
531
532bool SaveFrameRTTI(const wxString &testFileName, wxDynamicObject *frame)
533{
534 // setup the XML document
535 wxXmlDocument xml;
536 wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE,
537 "TestXTI", "This is the content");
538 xml.SetRoot(root);
539
540 // setup the XTI writer and persister
541 wxObjectXmlWriter writer(root);
542 MyDesignerPersister persister(frame);
543
544 // write the given wxObject into the XML document
1bf29304 545 wxStringToAnyHashMap empty;
cc3977bf
SC
546 writer.WriteObject( frame, frame->GetClassInfo(), &persister,
547 wxString("myTestFrame"), empty );
548
549 return xml.Save(testFileName);
550}
551
552wxDynamicObject* LoadFrameRTTI(const wxString &fileName)
553{
554 // load the XML document
555 wxXmlDocument xml;
556 if (!xml.Load(fileName))
557 return NULL;
558
559 wxXmlNode *root = xml.GetRoot();
560 if (root->GetName() != "TestXTI")
561 return NULL;
562
563 // now depersist the wxFrame we saved into it using wxObjectRuntimeReaderCallback
564 wxObjectRuntimeReaderCallback Callbacks;
565 wxObjectXmlReader Reader( root );
566 int obj = Reader.ReadObject( wxString("myTestFrame"), &Callbacks );
567 return (wxDynamicObject*)Callbacks.GetObject( obj );
568}
569
570bool GenerateFrameRTTICode(const wxString &inFileName, const wxString &outFileName)
571{
572 // is loading the streamed out component from xml and writing code that
573 // will create the same component
574
575 wxFFileOutputStream fos( outFileName );
576 wxTextOutputStream tos( fos );
577 if (!fos.IsOk())
578 return false;
579
580 wxXmlDocument xml;
581 if (!xml.Load(inFileName))
582 return false;
583
584 wxXmlNode *root = xml.GetRoot();
585 if (root->GetName() != "TestXTI")
586 return false;
587
588 // read the XML file using the wxObjectCodeReaderCallback
1bf29304
SC
589
590 wxString headerincludes;
591 wxString sourcecode;
592 wxObjectCodeReaderCallback Callbacks(headerincludes,sourcecode);
cc3977bf
SC
593 wxObjectXmlReader Reader(root);
594
595 // ReadObject will return the ID of the object read??
596 Reader.ReadObject( wxString("myTestFrame"), &Callbacks );
597
1bf29304
SC
598 // header preamble
599 tos <<
600 "#include \"wx/wxprec.h\" \n#ifdef __BORLANDC__\n#pragma hdrstop\n#endif\n#ifndef WX_PRECOMP\n#include \"wx/wx.h\" \n#endif\n\n";
601 // add object includes
602 tos.WriteString( headerincludes );
603
604 tos << "\n\nvoid test()\n{";
605 tos.WriteString( sourcecode );
606 tos << "}";
cc3977bf
SC
607 return true;
608}
609
610
611
612
613// ----------------------------------------------------------------------------
614// MyFrame event handlers
615// ----------------------------------------------------------------------------
616
617void MyFrame::OnPersist(wxCommandEvent& WXUNUSED(event))
618{
619 // first create a frame using XTI calls
620 wxDynamicObject *frame = CreateFrameRTTI();
621 if (!frame)
622 {
623 wxLogError(wxT("Cannot create the XTI frame!"));
624 return;
625 }
626
627 // show the frame we're going to save to the user
628 wxFrame *trueFrame = wx_dynamic_cast(wxFrame *, frame->GetSuperClassInstance() );
629 trueFrame->Show();
630
631 // ask the user where to save it
632 wxFileDialog dlg(this, wxT("Where should the frame be saved?"),
633 wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
634 wxFD_SAVE);
635 if (dlg.ShowModal() == wxID_CANCEL)
636 return;
637
638 // then save it to a test XML file
639 if (!SaveFrameRTTI(dlg.GetPath(), frame))
640 {
641 wxLogError(wxT("Cannot save the XTI frame into '%s'"), dlg.GetPath());
642 return;
643 }
644
645 // now simply delete it
646 delete frame;
647}
648
649void MyFrame::OnDepersist(wxCommandEvent& WXUNUSED(event))
650{
651 // ask the user which file to load
652 wxFileDialog dlg(this, wxT("Which file contains the frame to depersist?"),
653 wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
654 wxFD_OPEN);
655 if (dlg.ShowModal() == wxID_CANCEL)
656 return;
657
658 wxObject *frame = LoadFrameRTTI(dlg.GetPath());
659 if (!frame)
660 {
661 wxLogError(wxT("Could not depersist the wxFrame from '%s'"), dlg.GetPath());
662 return;
663 }
664
665 wxFrame *trueFrame = wx_dynamic_cast(wxFrame*, frame );
666 if ( !trueFrame )
667 {
668 wxDynamicObject* dyno = wx_dynamic_cast(wxDynamicObject*, frame );
669 if ( dyno )
670 trueFrame = wx_dynamic_cast(wxFrame *, dyno->GetSuperClassInstance() );
671 }
672
673 if ( trueFrame )
674 trueFrame->Show();
675 else
676 wxLogError(wxT("Could not show the frame"));
677}
678
679void MyFrame::OnGenerateCode(wxCommandEvent& WXUNUSED(event))
680{
681 // ask the user which file to load
682 wxFileDialog dlg(this, wxT("Which file contains the frame to work on?"),
683 wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
684 wxFD_OPEN);
685 if (dlg.ShowModal() == wxID_CANCEL)
686 return;
687
688 // ask the user which file to load
689 wxFileDialog dlg2(this, wxT("Where should the C++ code be saved?"),
690 wxEmptyString, wxT("test.cpp"), wxT("Source files (*.cpp)|*.cpp"),
691 wxFD_SAVE);
692 if (dlg2.ShowModal() == wxID_CANCEL)
693 return;
694
695 // do generate code
696 if (!GenerateFrameRTTICode(dlg.GetPath(), dlg2.GetPath()))
697 {
698 wxLogError(wxT("Could not generate the code for the frame!"));
699 return;
700 }
701
702 // show the generated code
703 {
704 wxFileInputStream f(dlg2.GetPath());
705 wxStringOutputStream str;
706 f.Read(str);
707
708 wxDialog dlg(this, wxID_ANY, wxT("Generated code"),
709 wxDefaultPosition, wxDefaultSize,
710 wxRESIZE_BORDER|wxDEFAULT_DIALOG_STYLE);
711 wxPanel *panel = new wxPanel(&dlg);
712 wxSizer *sz = new wxBoxSizer(wxVERTICAL);
713 sz->Add(new wxTextCtrl(panel, wxID_ANY, str.GetString(),
714 wxDefaultPosition, wxDefaultSize,
715 wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP),
716 1, wxGROW|wxALL, 5);
717 sz->Add(new wxButton(panel, wxID_OK), 0, wxALIGN_RIGHT|wxALL, 5);
718 panel->SetSizerAndFit(sz);
719 dlg.ShowModal();
720 }
721}
722
723void MyFrame::OnDumpClasses(wxCommandEvent& WXUNUSED(event))
724{
725 ClassListDialog dlg(this);
726 dlg.ShowModal();
727}
728
729void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
730{
731 // true is to force the frame to close
732 Close(true);
733}
734
735void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
736{
737 wxMessageBox(wxString::Format(
ebfe373e
DS
738 wxT("Welcome to %s!\n")
739 wxT("\n")
740 wxT("This sample demonstrates wxWidgets eXtended RTTI (XTI) system."),
cc3977bf
SC
741 wxVERSION_STRING
742 ),
ebfe373e 743 wxT("About wxWidgets XTI sample"),
cc3977bf
SC
744 wxOK | wxICON_INFORMATION,
745 this);
746}