1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: eXtended RTTI support sample
4 // Author: Stefan Csomor, Francesco Montorsi
7 // RCS-ID: $Id: xti.cpp 48407 2007-08-26 23:17:23Z FM $
8 // Copyright: (c) Stefan Csomor, Francesco Montorsi
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers)
34 #include "wx/variant.h"
35 #include "wx/xml/xml.h"
37 #include "wx/notebook.h"
39 #include "wx/spinbutt.h"
40 #include "wx/spinctrl.h"
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"
49 #include "classlist.h"
50 #include "codereadercallback.h"
52 #if !wxUSE_EXTENDED_RTTI
53 #error This sample requires XTI (eXtended RTTI) enabled
57 // ----------------------------------------------------------------------------
59 // ----------------------------------------------------------------------------
61 #if !defined(__WXMSW__) && !defined(__WXPM__)
62 #include "../sample.xpm"
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
69 // Define a new application type, each program should derive a class from wxApp
70 class MyApp
: public wxApp
73 virtual bool OnInit();
76 // Define a new frame type: this is going to be our main frame
77 class MyFrame
: public wxFrame
81 MyFrame(const wxString
& title
);
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
);
91 // any class wishing to process wxWidgets events must use this macro
92 wxDECLARE_EVENT_TABLE()
95 // ----------------------------------------------------------------------------
97 // ----------------------------------------------------------------------------
99 // IDs for the controls and the menu commands
103 Minimal_Persist
= wxID_HIGHEST
,
105 Minimal_GenerateCode
,
107 Minimal_Quit
= wxID_EXIT
,
108 Minimal_About
= wxID_ABOUT
111 // ----------------------------------------------------------------------------
112 // event tables and other macros for wxWidgets
113 // ----------------------------------------------------------------------------
115 BEGIN_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
)
124 wxIMPLEMENT_APP(MyApp
)
126 // ============================================================================
128 // ============================================================================
130 void RegisterFrameRTTI();
132 // ----------------------------------------------------------------------------
133 // the application class
134 // ----------------------------------------------------------------------------
138 if ( !wxApp
::OnInit() )
143 // create the main application window
144 MyFrame
*frame
= new MyFrame(_T("Extended RTTI sample"));
146 // and show it (the frames, unlike simple controls, are not shown when
147 // created initially)
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.
156 // ----------------------------------------------------------------------------
158 // ----------------------------------------------------------------------------
160 MyFrame
::MyFrame(const wxString
& title
)
161 : wxFrame(NULL
, wxID_ANY
, title
, wxDefaultPosition
, wxSize(300, 200))
163 // set the frame icon
164 SetIcon(wxICON(sample
));
168 wxMenu
*fileMenu
= new wxMenu
;
170 // the "About" item should be in the help menu
171 wxMenu
*helpMenu
= new wxMenu
;
172 helpMenu
->Append(Minimal_About
, _T("&About...\tF1"), _T("Show about dialog"));
174 fileMenu
->Append(Minimal_Persist
, _T("Persist a wxFrame to XML..."),
175 _T("Creates a wxFrame using wxXTI and saves its description as XML"));
176 fileMenu
->Append(Minimal_Depersist
, _T("Depersist XML file..."),
177 _T("Loads the description of wxFrame from XML"));
178 fileMenu
->Append(Minimal_GenerateCode
, _T("Generate code for a wxFrame saved to XML..."),
179 _T("Generates the C++ code which belong to a persisted wxFrame"));
180 fileMenu
->AppendSeparator();
181 fileMenu
->Append(Minimal_DumpClasses
, _T("Dump registered classes..."),
182 _T("Dumps the description of all wxWidgets classes registered in XTI"));
183 fileMenu
->AppendSeparator();
184 fileMenu
->Append(Minimal_Quit
, _T("E&xit\tAlt-X"), _T("Quit this program"));
186 // now append the freshly created menu to the menu bar...
187 wxMenuBar
*menuBar
= new wxMenuBar();
188 menuBar
->Append(fileMenu
, _T("&File"));
189 menuBar
->Append(helpMenu
, _T("&Help"));
191 // ... and attach this menu bar to the frame
193 #endif // wxUSE_MENUS
196 // create a status bar just for fun (by default with 1 pane only)
198 SetStatusText(_T("Welcome to wxWidgets!"));
199 #endif // wxUSE_STATUSBAR
204 // ----------------------------------------------------------------------------
206 // ----------------------------------------------------------------------------
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:
212 // class MyXTIFrame : public wxFrame
222 // bool Create(wxWindow *parent,
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)
230 // return wxFrame::Create( parent, id, title, pos, size, style, name );
233 // void SetButton( wxButton * button ) { m_button = button; }
234 // wxButton* GetButton() const { return m_button; }
236 // void ButtonClickHandler( wxEvent & WXUNUSED(event) )
238 // wxMessageBox( "Button Clicked ", "Hi!", wxOK );
242 // wxButton* m_button;
244 // DECLARE_EVENT_TABLE()
245 // DECLARE_DYNAMIC_CLASS_NO_COPY(MyXTIFrame)
248 // IMPLEMENT_DYNAMIC_CLASS_XTI(MyXTIFrame, MyXTIFrame, "x.h")
250 // WX_BEGIN_PROPERTIES_TABLE(MyXTIFrame)
251 // WX_PROPERTY( Button, wxButton*, SetButton, GetButton, )
252 // WX_END_PROPERTIES_TABLE()
254 // WX_BEGIN_HANDLERS_TABLE(MyXTIFrame)
255 // WX_HANDLER( ButtonClickHandler, wxCommandEvent )
256 // WX_END_HANDLERS_TABLE()
258 // WX_CONSTRUCTOR_5( MyXTIFrame, wxWindow*, Parent, wxWindowID, Id,
259 // wxString, Title, wxPoint, Position, wxSize, Size )
261 // BEGIN_EVENT_TABLE(MyXTIFrame, wxFrame)
264 // the following class "persists" (i.e. saves) a wxFrame into a wxObjectWriter
266 class MyDesignerPersister
: public wxObjectReaderCallback
269 MyDesignerPersister( wxDynamicObject
* frame
)
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
)
281 // this approach would be used it the handler would not
282 // be connected really in the designer, so we have to supply
284 if ( object
== m_frame
->GetProperty(wxT("Button")).GetAsObject() &&
285 propInfo
== wxCLASSINFO( wxButton
)->FindPropertyInfo("OnClick") )
288 handlerInfo
= m_frame
->GetClassInfo()->
289 FindHandlerInfo("ButtonClickHandler");
296 wxDynamicObject
*m_frame
;
299 // sometimes linkers (at least MSVC and GCC ones) optimize the final EXE
300 // even in debug mode pruning the object files which he "thinks" are useless;
301 // thus the classes defined in those files won't be available in the XTI
302 // table and the program will fail to allocate them.
303 // The following macro implements a simple hack to ensure that a given
304 // class is linked in.
306 // TODO: in wx/link.h there are already similar macros (also more "optimized":
307 // don't need the creation of fake object) which however require to use
308 // the wxFORCE_LINK_THIS_MODULE() macro inside the source files corresponding
309 // to the class being discarded.
311 #define wxENSURE_CLASS_IS_LINKED(x) { x test; }
313 void RegisterFrameRTTI()
315 // set up the RTTI info for a class (MyXTIFrame) which
316 // is not defined anywhere in this program
317 wxDynamicClassInfo
*dyninfo
=
318 wx_dynamic_cast( wxDynamicClassInfo
*, wxClassInfo
::FindClass(wxT("MyXTIFrame")));
319 if ( dyninfo
== NULL
)
321 dyninfo
= new wxDynamicClassInfo(wxT("myxtiframe.h"),
323 CLASSINFO(wxFrame
) );
325 // this class has a property named "Button" and the relative handler:
326 dyninfo
->AddProperty("Button", wxGetTypeInfo((wxButton
**) NULL
));
327 dyninfo
->AddHandler("ButtonClickHandler",
328 NULL
/* no instance of the handler method */, CLASSINFO( wxEvent
) );
332 wxDynamicObject
* CreateFrameRTTI()
335 wxVariantBase Params
[10];
337 // the class is now part of XTI internal table so that we can
338 // get a pointer to it just searching it like any other class:
340 wxClassInfo
*info
= wxClassInfo
::FindClass(wxT("MyXTIFrame"));
342 wxDynamicObject
* frameWrapper
=
343 wx_dynamic_cast(wxDynamicObject
*, info
->CreateObject() );
344 Params
[0] = wxVariantBase((wxWindow
*)(NULL
));
345 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
346 Params
[2] = wxVariantBase(wxString(wxT("This is a frame created from XTI")));
347 Params
[3] = wxVariantBase(wxPoint(-1,-1));
348 Params
[4] = wxVariantBase(wxSize(400,300));
349 Params
[5] = wxVariantBase((long)wxDEFAULT_FRAME_STYLE
);
350 wxASSERT( info
->Create(frameWrapper
, 6, Params
));
351 frame
= wx_dynamic_cast(wxFrame
*, frameWrapper
->GetSuperClassInstance());
353 // now build a notebook inside it:
354 wxNotebook
* notebook
;
355 info
= wxClassInfo
::FindClass("wxNotebook");
357 notebook
= wxDynamicCast( info
->CreateObject(), wxNotebook
);
358 Params
[0] = wxVariantBase((wxWindow
*)frame
);
359 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
360 Params
[2] = wxVariantBase(wxPoint( 10, 10 ));
361 Params
[3] = wxVariantBase(wxDefaultSize
);
362 Params
[4] = wxVariantBase((long)0);
363 wxASSERT( info
->Create(notebook
, 5, Params
));
368 info
= wxClassInfo
::FindClass("wxPanel");
370 panel
= wxDynamicCast( info
->CreateObject(), wxPanel
);
371 Params
[0] = wxVariantBase((wxWindow
*)(notebook
));
372 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
373 Params
[2] = wxVariantBase(wxPoint(-1,-1));
374 Params
[3] = wxVariantBase(wxSize(-1,-1));
375 Params
[4] = wxVariantBase((long)0);
376 Params
[5] = wxVariantBase(wxString(wxT("Hello")));
377 wxASSERT( info
->Create(panel
, 6, Params
));
378 notebook
->AddPage( panel
, "Buttons" );
381 info
= wxClassInfo
::FindClass("wxButton");
383 button
= wxDynamicCast( info
->CreateObject(), wxButton
);
384 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
385 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
386 Params
[2] = wxVariantBase(wxString(wxT("Click Me!")));
387 Params
[3] = wxVariantBase(wxPoint( 10, 10 ));
388 Params
[4] = wxVariantBase(wxSize(-1,-1));
389 Params
[5] = wxVariantBase((long)0);
390 wxASSERT( info
->Create(button
, 6, Params
));
391 frameWrapper
->SetProperty( "Button", wxVariantBase( button
) );
393 // other controls page
395 info
= wxClassInfo
::FindClass("wxPanel");
397 panel
= wxDynamicCast( info
->CreateObject(), wxPanel
);
398 Params
[0] = wxVariantBase((wxWindow
*)(notebook
));
399 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
400 Params
[2] = wxVariantBase(wxPoint(-1,-1));
401 Params
[3] = wxVariantBase(wxSize(-1,-1));
402 Params
[4] = wxVariantBase((long)0);
403 Params
[5] = wxVariantBase(wxString(wxT("Hello")));
404 wxASSERT( info
->Create(panel
, 6, Params
));
405 notebook
->AddPage( panel
, "Other Standard controls" );
408 info
= wxClassInfo
::FindClass("wxCheckBox");
410 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
411 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
412 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
413 Params
[2] = wxVariantBase(wxString(wxT("A Checkbox")));
414 Params
[3] = wxVariantBase(wxPoint( 10, 10 ));
415 Params
[4] = wxVariantBase(wxSize(-1,-1));
416 Params
[5] = wxVariantBase((long)0);
417 wxASSERT( info
->Create(control
, 6, Params
));
419 info
= wxClassInfo
::FindClass("wxRadioButton");
421 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
422 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
423 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
424 Params
[2] = wxVariantBase(wxString(wxT("A Radiobutton")));
425 Params
[3] = wxVariantBase(wxPoint( 10, 30 ));
426 Params
[4] = wxVariantBase(wxSize(-1,-1));
427 Params
[5] = wxVariantBase((long)0);
428 wxASSERT( info
->Create(control
, 6, Params
));
430 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
431 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
432 Params
[2] = wxVariantBase(wxString(wxT("Another One")));
433 Params
[3] = wxVariantBase(wxPoint( 10, 50 ));
434 wxASSERT( info
->Create(control
, 6, Params
));
436 info
= wxClassInfo
::FindClass("wxStaticText");
438 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
439 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
440 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
441 Params
[2] = wxVariantBase(wxString(wxT("A Static Text!")));
442 Params
[3] = wxVariantBase(wxPoint( 10, 70 ));
443 Params
[4] = wxVariantBase(wxSize(-1,-1));
444 Params
[5] = wxVariantBase((long)0);
445 wxASSERT( info
->Create(control
, 6, Params
));
447 info
= wxClassInfo
::FindClass("wxStaticBox");
449 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
450 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
451 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
452 Params
[2] = wxVariantBase(wxString(wxT("A Static Box")));
453 Params
[3] = wxVariantBase(wxPoint( 10, 90 ));
454 Params
[4] = wxVariantBase(wxSize(100,80));
455 Params
[5] = wxVariantBase((long)0);
456 wxASSERT( info
->Create(control
, 6, Params
));
458 info
= wxClassInfo
::FindClass("wxTextCtrl");
460 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
461 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
462 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
463 Params
[2] = wxVariantBase(wxString(wxT("A Text Control")));
464 Params
[3] = wxVariantBase(wxPoint( 10, 200 ));
465 Params
[4] = wxVariantBase(wxSize(-1,-1));
466 Params
[5] = wxVariantBase((long)0);
467 wxASSERT( info
->Create(control
, 6, Params
));
469 // spins and gauges page
471 info
= wxClassInfo
::FindClass("wxPanel");
473 panel
= wxDynamicCast( info
->CreateObject(), wxPanel
);
474 Params
[0] = wxVariantBase((wxWindow
*)(notebook
));
475 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
476 Params
[2] = wxVariantBase(wxPoint(-1,-1));
477 Params
[3] = wxVariantBase(wxSize(-1,-1));
478 Params
[4] = wxVariantBase((long)0);
479 Params
[5] = wxVariantBase(wxString(wxT("Hello")));
480 wxASSERT( info
->Create(panel
, 6, Params
));
481 notebook
->AddPage( panel
, "Spins and Sliders" );
483 wxENSURE_CLASS_IS_LINKED(wxSpinButton
);
485 info
= wxClassInfo
::FindClass("wxSpinButton");
487 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
488 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
489 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
490 Params
[2] = wxVariantBase(wxPoint( 10, 10 ));
491 Params
[3] = wxVariantBase(wxSize(-1,-1));
492 Params
[4] = wxVariantBase((long)wxSP_VERTICAL
| wxSP_ARROW_KEYS
);
493 wxASSERT( info
->Create(control
, 5, Params
));
495 wxENSURE_CLASS_IS_LINKED(wxSpinCtrl
);
497 info
= wxClassInfo
::FindClass("wxSpinCtrl");
499 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
500 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
501 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
502 Params
[2] = wxVariantBase(wxString("20"));
503 Params
[3] = wxVariantBase(wxPoint( 40, 10 ));
504 Params
[4] = wxVariantBase(wxSize(40,-1));
505 Params
[5] = wxVariantBase((long) wxSP_ARROW_KEYS
);
506 wxASSERT( info
->Create(control
, 6, Params
));
508 // MSVC likes to exclude from link wxGauge...
509 wxENSURE_CLASS_IS_LINKED(wxGauge
)
510 wxENSURE_CLASS_IS_LINKED(wxCheckBox
)
511 wxENSURE_CLASS_IS_LINKED(wxSpinCtrl
)
514 // under wxMSW wxGauge is simply #defined to wxGauge95
515 info
= wxClassInfo
::FindClass("wxGauge95");
517 info
= wxClassInfo
::FindClass("wxGauge");
520 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
521 Params
[0] = wxVariantBase((wxWindow
*)(panel
));
522 Params
[1] = wxVariantBase(wxWindowID(baseID
++));
523 Params
[2] = wxVariantBase((int) 100);
524 Params
[3] = wxVariantBase(wxPoint( 10, 50 ));
525 Params
[4] = wxVariantBase(wxSize(-1,-1));
526 Params
[5] = wxVariantBase((long) wxGA_HORIZONTAL
);
527 wxASSERT( info
->Create(control
, 6, Params
));
528 wx_dynamic_cast(wxGauge
*, control
)->SetValue(20);
533 bool SaveFrameRTTI(const wxString
&testFileName
, wxDynamicObject
*frame
)
535 // setup the XML document
537 wxXmlNode
*root
= new wxXmlNode(wxXML_ELEMENT_NODE
,
538 "TestXTI", "This is the content");
541 // setup the XTI writer and persister
542 wxObjectXmlWriter
writer(root
);
543 MyDesignerPersister
persister(frame
);
545 // write the given wxObject into the XML document
546 wxVariantBaseArray empty
;
547 writer
.WriteObject( frame
, frame
->GetClassInfo(), &persister
,
548 wxString("myTestFrame"), empty
);
550 return xml
.Save(testFileName
);
553 wxDynamicObject
* LoadFrameRTTI(const wxString
&fileName
)
555 // load the XML document
557 if (!xml
.Load(fileName
))
560 wxXmlNode
*root
= xml
.GetRoot();
561 if (root
->GetName() != "TestXTI")
564 // now depersist the wxFrame we saved into it using wxObjectRuntimeReaderCallback
565 wxObjectRuntimeReaderCallback Callbacks
;
566 wxObjectXmlReader
Reader( root
);
567 int obj
= Reader
.ReadObject( wxString("myTestFrame"), &Callbacks
);
568 return (wxDynamicObject
*)Callbacks
.GetObject( obj
);
571 bool GenerateFrameRTTICode(const wxString
&inFileName
, const wxString
&outFileName
)
573 // is loading the streamed out component from xml and writing code that
574 // will create the same component
576 wxFFileOutputStream
fos( outFileName
);
577 wxTextOutputStream
tos( fos
);
582 if (!xml
.Load(inFileName
))
585 wxXmlNode
*root
= xml
.GetRoot();
586 if (root
->GetName() != "TestXTI")
589 // read the XML file using the wxObjectCodeReaderCallback
590 wxObjectCodeReaderCallback
Callbacks(&tos
);
591 wxObjectXmlReader
Reader(root
);
593 // ReadObject will return the ID of the object read??
594 Reader
.ReadObject( wxString("myTestFrame"), &Callbacks
);
602 // ----------------------------------------------------------------------------
603 // MyFrame event handlers
604 // ----------------------------------------------------------------------------
606 void MyFrame
::OnPersist(wxCommandEvent
& WXUNUSED(event
))
608 // first create a frame using XTI calls
609 wxDynamicObject
*frame
= CreateFrameRTTI();
612 wxLogError(wxT("Cannot create the XTI frame!"));
616 // show the frame we're going to save to the user
617 wxFrame
*trueFrame
= wx_dynamic_cast(wxFrame
*, frame
->GetSuperClassInstance() );
620 // ask the user where to save it
621 wxFileDialog
dlg(this, wxT("Where should the frame be saved?"),
622 wxEmptyString
, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
624 if (dlg
.ShowModal() == wxID_CANCEL
)
627 // then save it to a test XML file
628 if (!SaveFrameRTTI(dlg
.GetPath(), frame
))
630 wxLogError(wxT("Cannot save the XTI frame into '%s'"), dlg
.GetPath());
634 // now simply delete it
638 void MyFrame
::OnDepersist(wxCommandEvent
& WXUNUSED(event
))
640 // ask the user which file to load
641 wxFileDialog
dlg(this, wxT("Which file contains the frame to depersist?"),
642 wxEmptyString
, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
644 if (dlg
.ShowModal() == wxID_CANCEL
)
647 wxObject
*frame
= LoadFrameRTTI(dlg
.GetPath());
650 wxLogError(wxT("Could not depersist the wxFrame from '%s'"), dlg
.GetPath());
654 wxFrame
*trueFrame
= wx_dynamic_cast(wxFrame
*, frame
);
657 wxDynamicObject
* dyno
= wx_dynamic_cast(wxDynamicObject
*, frame
);
659 trueFrame
= wx_dynamic_cast(wxFrame
*, dyno
->GetSuperClassInstance() );
665 wxLogError(wxT("Could not show the frame"));
668 void MyFrame
::OnGenerateCode(wxCommandEvent
& WXUNUSED(event
))
670 // ask the user which file to load
671 wxFileDialog
dlg(this, wxT("Which file contains the frame to work on?"),
672 wxEmptyString
, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
674 if (dlg
.ShowModal() == wxID_CANCEL
)
677 // ask the user which file to load
678 wxFileDialog
dlg2(this, wxT("Where should the C++ code be saved?"),
679 wxEmptyString
, wxT("test.cpp"), wxT("Source files (*.cpp)|*.cpp"),
681 if (dlg2
.ShowModal() == wxID_CANCEL
)
685 if (!GenerateFrameRTTICode(dlg
.GetPath(), dlg2
.GetPath()))
687 wxLogError(wxT("Could not generate the code for the frame!"));
691 // show the generated code
693 wxFileInputStream
f(dlg2
.GetPath());
694 wxStringOutputStream str
;
697 wxDialog
dlg(this, wxID_ANY
, wxT("Generated code"),
698 wxDefaultPosition
, wxDefaultSize
,
699 wxRESIZE_BORDER
|wxDEFAULT_DIALOG_STYLE
);
700 wxPanel
*panel
= new wxPanel(&dlg
);
701 wxSizer
*sz
= new wxBoxSizer(wxVERTICAL
);
702 sz
->Add(new wxTextCtrl(panel
, wxID_ANY
, str
.GetString(),
703 wxDefaultPosition
, wxDefaultSize
,
704 wxTE_MULTILINE
|wxTE_READONLY
|wxTE_DONTWRAP
),
706 sz
->Add(new wxButton(panel
, wxID_OK
), 0, wxALIGN_RIGHT
|wxALL
, 5);
707 panel
->SetSizerAndFit(sz
);
712 void MyFrame
::OnDumpClasses(wxCommandEvent
& WXUNUSED(event
))
714 ClassListDialog
dlg(this);
718 void MyFrame
::OnQuit(wxCommandEvent
& WXUNUSED(event
))
720 // true is to force the frame to close
724 void MyFrame
::OnAbout(wxCommandEvent
& WXUNUSED(event
))
726 wxMessageBox(wxString
::Format(
727 _T("Welcome to %s!\n")
729 _T("This sample demonstrates wxWidgets eXtended RTTI (XTI) system."),
732 _T("About wxWidgets XTI sample"),
733 wxOK
| wxICON_INFORMATION
,