1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: eXtended RTTI support sample
4 // Author: Stefan Csomor, Francesco Montorsi
7 // Copyright: (c) Stefan Csomor, Francesco Montorsi
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
26 // for all others, include the necessary headers (this file is usually all you
27 // need because it includes almost all "standard" wxWidgets headers)
33 #include "wx/variant.h"
34 #include "wx/xml/xml.h"
36 #include "wx/notebook.h"
38 #include "wx/spinbutt.h"
39 #include "wx/spinctrl.h"
41 #include "wx/xtistrm.h"
42 #include "wx/xtixml.h"
43 #include "wx/txtstrm.h"
44 #include "wx/wfstream.h"
45 #include "wx/sstream.h"
46 #include "wx/spinctrl.h"
48 #include "classlist.h"
49 #include "codereadercallback.h"
51 #if !wxUSE_EXTENDED_RTTI
52 #error This sample requires XTI (eXtended RTTI) enabled
56 // ----------------------------------------------------------------------------
58 // ----------------------------------------------------------------------------
60 #ifndef wxHAS_IMAGES_IN_RESOURCES
61 #include "../sample.xpm"
64 // ----------------------------------------------------------------------------
66 // ----------------------------------------------------------------------------
68 // Define a new application type, each program should derive a class from wxApp
69 class MyApp
: public wxApp
72 virtual bool OnInit();
75 // Define a new frame type: this is going to be our main frame
76 class MyFrame
: public wxFrame
80 MyFrame(const wxString
& title
);
82 void OnPersist(wxCommandEvent
& event
);
83 void OnDepersist(wxCommandEvent
& event
);
84 void OnGenerateCode(wxCommandEvent
& event
);
85 void OnDumpClasses(wxCommandEvent
& event
);
86 void OnQuit(wxCommandEvent
& event
);
87 void OnAbout(wxCommandEvent
& event
);
90 // any class wishing to process wxWidgets events must use this macro
91 wxDECLARE_EVENT_TABLE();
94 // ----------------------------------------------------------------------------
96 // ----------------------------------------------------------------------------
98 // IDs for the controls and the menu commands
102 Minimal_Persist
= wxID_HIGHEST
,
104 Minimal_GenerateCode
,
106 Minimal_Quit
= wxID_EXIT
,
107 Minimal_About
= wxID_ABOUT
110 // ----------------------------------------------------------------------------
111 // event tables and other macros for wxWidgets
112 // ----------------------------------------------------------------------------
114 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
115 EVT_MENU(Minimal_Persist
, MyFrame::OnPersist
)
116 EVT_MENU(Minimal_Depersist
, MyFrame::OnDepersist
)
117 EVT_MENU(Minimal_GenerateCode
, MyFrame::OnGenerateCode
)
118 EVT_MENU(Minimal_DumpClasses
, MyFrame::OnDumpClasses
)
119 EVT_MENU(Minimal_Quit
, MyFrame::OnQuit
)
120 EVT_MENU(Minimal_About
, MyFrame::OnAbout
)
123 wxIMPLEMENT_APP(MyApp
);
125 // ============================================================================
127 // ============================================================================
129 void RegisterFrameRTTI();
131 // ----------------------------------------------------------------------------
132 // the application class
133 // ----------------------------------------------------------------------------
137 if ( !wxApp::OnInit() )
142 // create the main application window
143 MyFrame
*frame
= new MyFrame(wxT("Extended RTTI sample"));
145 // and show it (the frames, unlike simple controls, are not shown when
146 // created initially)
149 // success: wxApp::OnRun() will be called which will enter the main message
150 // loop and the application will run. If we returned false here, the
151 // application would exit immediately.
155 // ----------------------------------------------------------------------------
157 // ----------------------------------------------------------------------------
159 MyFrame::MyFrame(const wxString
& title
)
160 : wxFrame(NULL
, wxID_ANY
, title
, wxDefaultPosition
, wxSize(300, 200))
162 // set the frame icon
163 SetIcon(wxICON(sample
));
167 wxMenu
*fileMenu
= new wxMenu
;
169 // the "About" item should be in the help menu
170 wxMenu
*helpMenu
= new wxMenu
;
171 helpMenu
->Append(Minimal_About
, wxT("&About\tF1"), wxT("Show about dialog"));
173 fileMenu
->Append(Minimal_Persist
, wxT("Persist a wxFrame to XML..."),
174 wxT("Creates a wxFrame using wxXTI and saves its description as XML"));
175 fileMenu
->Append(Minimal_Depersist
, wxT("Depersist XML file..."),
176 wxT("Loads the description of wxFrame from XML"));
177 fileMenu
->Append(Minimal_GenerateCode
, wxT("Generate code for a wxFrame saved to XML..."),
178 wxT("Generates the C++ code which belong to a persisted wxFrame"));
179 fileMenu
->AppendSeparator();
180 fileMenu
->Append(Minimal_DumpClasses
, wxT("Dump registered classes..."),
181 wxT("Dumps the description of all wxWidgets classes registered in XTI"));
182 fileMenu
->AppendSeparator();
183 fileMenu
->Append(Minimal_Quit
, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
185 // now append the freshly created menu to the menu bar...
186 wxMenuBar
*menuBar
= new wxMenuBar();
187 menuBar
->Append(fileMenu
, wxT("&File"));
188 menuBar
->Append(helpMenu
, wxT("&Help"));
190 // ... and attach this menu bar to the frame
192 #endif // wxUSE_MENUS
195 // create a status bar just for fun (by default with 1 pane only)
197 SetStatusText(wxT("Welcome to wxWidgets!"));
198 #endif // wxUSE_STATUSBAR
203 // ----------------------------------------------------------------------------
205 // ----------------------------------------------------------------------------
207 // this is the kind of source code that would end up being generated by a
208 // designer corresponding to the information we are setting up via RTTI
209 // in the CreateFrameRTTI function:
211 // class MyXTIFrame : public wxFrame
221 // bool Create(wxWindow *parent,
223 // const wxString& title,
224 // const wxPoint& pos = wxDefaultPosition,
225 // const wxSize& size = wxDefaultSize,
226 // long style = wxDEFAULT_FRAME_STYLE,
227 // const wxString& name = wxFrameNameStr)
229 // return wxFrame::Create( parent, id, title, pos, size, style, name );
232 // void SetButton( wxButton * button ) { m_button = button; }
233 // wxButton* GetButton() const { return m_button; }
235 // void ButtonClickHandler( wxEvent & WXUNUSED(event) )
237 // wxMessageBox( "Button Clicked ", "Hi!", wxOK );
241 // wxButton* m_button;
243 // DECLARE_EVENT_TABLE()
244 // DECLARE_DYNAMIC_CLASS_NO_COPY(MyXTIFrame)
247 // IMPLEMENT_DYNAMIC_CLASS_XTI(MyXTIFrame, MyXTIFrame, "x.h")
249 // WX_BEGIN_PROPERTIES_TABLE(MyXTIFrame)
250 // WX_PROPERTY( Button, wxButton*, SetButton, GetButton, )
251 // WX_END_PROPERTIES_TABLE()
253 // WX_BEGIN_HANDLERS_TABLE(MyXTIFrame)
254 // WX_HANDLER( ButtonClickHandler, wxCommandEvent )
255 // WX_END_HANDLERS_TABLE()
257 // WX_CONSTRUCTOR_5( MyXTIFrame, wxWindow*, Parent, wxWindowID, Id,
258 // wxString, Title, wxPoint, Position, wxSize, Size )
260 // BEGIN_EVENT_TABLE(MyXTIFrame, wxFrame)
263 // the following class "persists" (i.e. saves) a wxFrame into a wxObjectWriter
265 class MyDesignerPersister
: public wxObjectWriterCallback
268 MyDesignerPersister( wxDynamicObject
* frame
)
273 virtual bool BeforeWriteDelegate( wxObjectWriter
*WXUNUSED(writer
),
274 const wxObject
*object
,
275 const wxClassInfo
* WXUNUSED(classInfo
),
276 const wxPropertyInfo
*propInfo
,
277 const wxObject
*&eventSink
,
278 const wxHandlerInfo
* &handlerInfo
)
280 // this approach would be used if the handler would not
281 // be connected really in the designer, so we have to supply
283 const wxObject
* but
= wxAnyGetAsObjectPtr( m_frame
->GetProperty(wxT("Button")) );
284 if ( object
== but
&&
285 propInfo
== wxCLASSINFO( wxButton
)->FindPropertyInfo(wxT("OnClick")) )
288 handlerInfo
= m_frame
->GetClassInfo()->
289 FindHandlerInfo(wxT("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(wxT("Button"), wxGetTypeInfo((wxButton
**) NULL
));
327 dyninfo
->AddHandler(wxT("ButtonClickHandler"),
328 NULL
/* no instance of the handler method */, CLASSINFO( wxEvent
) );
332 wxDynamicObject
* CreateFrameRTTI()
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] = wxAny((wxWindow
*)(NULL
));
345 Params
[1] = wxAny(wxWindowID(baseID
++));
346 Params
[2] = wxAny(wxString(wxT("This is a frame created from XTI")));
347 Params
[3] = wxAny(wxPoint(-1,-1));
348 Params
[4] = wxAny(wxSize(400,300));
349 Params
[5] = wxAny((long)wxDEFAULT_FRAME_STYLE
);
350 wxASSERT( info
->Create(frameWrapper
, 6, Params
));
351 frame
= wx_dynamic_cast(wxFrame
*, frameWrapper
->GetSuperClassInstance());
354 // now build a notebook inside it:
355 wxNotebook
* notebook
;
356 info
= wxClassInfo::FindClass("wxNotebook");
358 notebook
= wxDynamicCast( info
->CreateObject(), wxNotebook
);
359 Params
[0] = wxAny((wxWindow
*)frame
);
360 Params
[1] = wxAny(wxWindowID(baseID
++));
361 Params
[2] = wxAny(wxPoint( 10, 10 ));
362 Params
[3] = wxAny(wxDefaultSize
);
363 Params
[4] = wxAny((long)0);
364 wxASSERT( info
->Create(notebook
, 5, Params
));
369 info
= wxClassInfo::FindClass("wxPanel");
371 panel
= wxDynamicCast( info
->CreateObject(), wxPanel
);
372 Params
[0] = wxAny((wxWindow
*)(notebook
));
373 Params
[1] = wxAny(wxWindowID(baseID
++));
374 Params
[2] = wxAny(wxPoint(-1,-1));
375 Params
[3] = wxAny(wxSize(-1,-1));
376 Params
[4] = wxAny((long)0);
377 Params
[5] = wxAny(wxString(wxT("Hello")));
378 wxASSERT( info
->Create(panel
, 6, Params
));
379 notebook
->AddPage( panel
, "Buttons" );
382 info
= wxClassInfo::FindClass("wxButton");
384 button
= wxDynamicCast( info
->CreateObject(), wxButton
);
385 Params
[0] = wxAny((wxWindow
*)(panel
));
386 Params
[1] = wxAny(wxWindowID(baseID
++));
387 Params
[2] = wxAny(wxString(wxT("Click Me!")));
388 Params
[3] = wxAny(wxPoint( 10, 10 ));
389 Params
[4] = wxAny(wxSize(-1,-1));
390 Params
[5] = wxAny((long)0);
391 wxASSERT( info
->Create(button
, 6, Params
));
392 frameWrapper
->SetProperty( wxT("Button"), wxAny( button
) );
394 // other controls page
396 info
= wxClassInfo::FindClass("wxPanel");
398 panel
= wxDynamicCast( info
->CreateObject(), wxPanel
);
399 Params
[0] = wxAny((wxWindow
*)(notebook
));
400 Params
[1] = wxAny(wxWindowID(baseID
++));
401 Params
[2] = wxAny(wxPoint(-1,-1));
402 Params
[3] = wxAny(wxSize(-1,-1));
403 Params
[4] = wxAny((long)0);
404 Params
[5] = wxAny(wxString(wxT("Hello")));
405 wxASSERT( info
->Create(panel
, 6, Params
));
406 notebook
->AddPage( panel
, "Other Standard controls" );
409 info
= wxClassInfo::FindClass("wxCheckBox");
411 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
412 Params
[0] = wxAny((wxWindow
*)(panel
));
413 Params
[1] = wxAny(wxWindowID(baseID
++));
414 Params
[2] = wxAny(wxString(wxT("A Checkbox")));
415 Params
[3] = wxAny(wxPoint( 10, 10 ));
416 Params
[4] = wxAny(wxSize(-1,-1));
417 Params
[5] = wxAny((long)0);
418 wxASSERT( info
->Create(control
, 6, Params
));
420 info
= wxClassInfo::FindClass("wxRadioButton");
422 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
423 Params
[0] = wxAny((wxWindow
*)(panel
));
424 Params
[1] = wxAny(wxWindowID(baseID
++));
425 Params
[2] = wxAny(wxString(wxT("A Radiobutton")));
426 Params
[3] = wxAny(wxPoint( 10, 30 ));
427 Params
[4] = wxAny(wxSize(-1,-1));
428 Params
[5] = wxAny((long)0);
429 wxASSERT( info
->Create(control
, 6, Params
));
431 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
432 Params
[1] = wxAny(wxWindowID(baseID
++));
433 Params
[2] = wxAny(wxString(wxT("Another One")));
434 Params
[3] = wxAny(wxPoint( 10, 50 ));
435 wxASSERT( info
->Create(control
, 6, Params
));
437 info
= wxClassInfo::FindClass("wxStaticText");
439 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
440 Params
[0] = wxAny((wxWindow
*)(panel
));
441 Params
[1] = wxAny(wxWindowID(baseID
++));
442 Params
[2] = wxAny(wxString(wxT("A Static Text!")));
443 Params
[3] = wxAny(wxPoint( 10, 70 ));
444 Params
[4] = wxAny(wxSize(-1,-1));
445 Params
[5] = wxAny((long)0);
446 wxASSERT( info
->Create(control
, 6, Params
));
448 info
= wxClassInfo::FindClass("wxStaticBox");
450 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
451 Params
[0] = wxAny((wxWindow
*)(panel
));
452 Params
[1] = wxAny(wxWindowID(baseID
++));
453 Params
[2] = wxAny(wxString(wxT("A Static Box")));
454 Params
[3] = wxAny(wxPoint( 10, 90 ));
455 Params
[4] = wxAny(wxSize(100,80));
456 Params
[5] = wxAny((long)0);
457 wxASSERT( info
->Create(control
, 6, Params
));
459 info
= wxClassInfo::FindClass("wxTextCtrl");
461 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
462 Params
[0] = wxAny((wxWindow
*)(panel
));
463 Params
[1] = wxAny(wxWindowID(baseID
++));
464 Params
[2] = wxAny(wxString(wxT("A Text Control")));
465 Params
[3] = wxAny(wxPoint( 10, 200 ));
466 Params
[4] = wxAny(wxSize(-1,-1));
467 Params
[5] = wxAny((long)0);
468 wxASSERT( info
->Create(control
, 6, Params
));
470 // spins and gauges page
472 info
= wxClassInfo::FindClass("wxPanel");
474 panel
= wxDynamicCast( info
->CreateObject(), wxPanel
);
475 Params
[0] = wxAny((wxWindow
*)(notebook
));
476 Params
[1] = wxAny(wxWindowID(baseID
++));
477 Params
[2] = wxAny(wxPoint(-1,-1));
478 Params
[3] = wxAny(wxSize(-1,-1));
479 Params
[4] = wxAny((long)0);
480 Params
[5] = wxAny(wxString(wxT("Hello")));
481 wxASSERT( info
->Create(panel
, 6, Params
));
482 notebook
->AddPage( panel
, "Spins and Sliders" );
484 wxENSURE_CLASS_IS_LINKED(wxSpinButton
);
486 info
= wxClassInfo::FindClass("wxSpinButton");
488 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
489 Params
[0] = wxAny((wxWindow
*)(panel
));
490 Params
[1] = wxAny(wxWindowID(baseID
++));
491 Params
[2] = wxAny(wxPoint( 10, 10 ));
492 Params
[3] = wxAny(wxSize(-1,-1));
493 Params
[4] = wxAny((long)wxSP_VERTICAL
| wxSP_ARROW_KEYS
);
494 wxASSERT( info
->Create(control
, 5, Params
));
496 wxENSURE_CLASS_IS_LINKED(wxSpinCtrl
);
498 info
= wxClassInfo::FindClass("wxSpinCtrl");
500 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
501 Params
[0] = wxAny((wxWindow
*)(panel
));
502 Params
[1] = wxAny(wxWindowID(baseID
++));
503 Params
[2] = wxAny(wxString("20"));
504 Params
[3] = wxAny(wxPoint( 40, 10 ));
505 Params
[4] = wxAny(wxSize(40,-1));
506 Params
[5] = wxAny((long) wxSP_ARROW_KEYS
);
507 wxASSERT( info
->Create(control
, 6, Params
));
509 // MSVC likes to exclude from link wxGauge...
510 wxENSURE_CLASS_IS_LINKED(wxGauge
)
511 wxENSURE_CLASS_IS_LINKED(wxCheckBox
)
512 wxENSURE_CLASS_IS_LINKED(wxSpinCtrl
)
514 info
= wxClassInfo::FindClass("wxGauge");
517 control
= wxDynamicCast( info
->CreateObject(), wxControl
);
518 Params
[0] = wxAny((wxWindow
*)(panel
));
519 Params
[1] = wxAny(wxWindowID(baseID
++));
520 Params
[2] = wxAny((int) 100);
521 Params
[3] = wxAny(wxPoint( 10, 50 ));
522 Params
[4] = wxAny(wxSize(-1,-1));
523 Params
[5] = wxAny((long) wxGA_HORIZONTAL
);
524 wxASSERT( info
->Create(control
, 6, Params
));
525 wx_dynamic_cast(wxGauge
*, control
)->SetValue(20);
531 bool SaveFrameRTTI(const wxString
&testFileName
, wxDynamicObject
*frame
)
533 // setup the XML document
535 wxXmlNode
*root
= new wxXmlNode(wxXML_ELEMENT_NODE
,
536 "TestXTI", "This is the content");
539 // setup the XTI writer and persister
540 wxObjectXmlWriter
writer(root
);
541 MyDesignerPersister
persister(frame
);
543 // write the given wxObject into the XML document
544 wxStringToAnyHashMap empty
;
545 writer
.WriteObject( frame
, frame
->GetClassInfo(), &persister
,
546 wxString("myTestFrame"), empty
);
548 return xml
.Save(testFileName
);
551 wxDynamicObject
* LoadFrameRTTI(const wxString
&fileName
)
553 // load the XML document
555 if (!xml
.Load(fileName
))
558 wxXmlNode
*root
= xml
.GetRoot();
559 if (root
->GetName() != "TestXTI")
562 // now depersist the wxFrame we saved into it using wxObjectRuntimeReaderCallback
563 wxObjectRuntimeReaderCallback Callbacks
;
564 wxObjectXmlReader
Reader( root
);
565 int obj
= Reader
.ReadObject( wxString("myTestFrame"), &Callbacks
);
566 return (wxDynamicObject
*)Callbacks
.GetObject( obj
);
569 bool GenerateFrameRTTICode(const wxString
&inFileName
, const wxString
&outFileName
)
571 // is loading the streamed out component from xml and writing code that
572 // will create the same component
574 wxFFileOutputStream
fos( outFileName
);
575 wxTextOutputStream
tos( fos
);
580 if (!xml
.Load(inFileName
))
583 wxXmlNode
*root
= xml
.GetRoot();
584 if (root
->GetName() != "TestXTI")
587 // read the XML file using the wxObjectCodeReaderCallback
589 wxString headerincludes
;
591 wxObjectCodeReaderCallback
Callbacks(headerincludes
,sourcecode
);
592 wxObjectXmlReader
Reader(root
);
594 // ReadObject will return the ID of the object read??
595 Reader
.ReadObject( wxString("myTestFrame"), &Callbacks
);
599 "#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";
600 // add object includes
601 tos
.WriteString( headerincludes
);
603 tos
<< "\n\nvoid test()\n{";
604 tos
.WriteString( sourcecode
);
612 // ----------------------------------------------------------------------------
613 // MyFrame event handlers
614 // ----------------------------------------------------------------------------
616 void MyFrame::OnPersist(wxCommandEvent
& WXUNUSED(event
))
618 // first create a frame using XTI calls
619 wxDynamicObject
*frame
= CreateFrameRTTI();
622 wxLogError(wxT("Cannot create the XTI frame!"));
626 // show the frame we're going to save to the user
627 wxFrame
*trueFrame
= wx_dynamic_cast(wxFrame
*, frame
->GetSuperClassInstance() );
630 // ask the user where to save it
631 wxFileDialog
dlg(this, wxT("Where should the frame be saved?"),
632 wxEmptyString
, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
634 if (dlg
.ShowModal() == wxID_CANCEL
)
637 // then save it to a test XML file
638 if (!SaveFrameRTTI(dlg
.GetPath(), frame
))
640 wxLogError(wxT("Cannot save the XTI frame into '%s'"), dlg
.GetPath());
644 // now simply delete it
648 void MyFrame::OnDepersist(wxCommandEvent
& WXUNUSED(event
))
650 // ask the user which file to load
651 wxFileDialog
dlg(this, wxT("Which file contains the frame to depersist?"),
652 wxEmptyString
, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
654 if (dlg
.ShowModal() == wxID_CANCEL
)
657 wxObject
*frame
= LoadFrameRTTI(dlg
.GetPath());
660 wxLogError(wxT("Could not depersist the wxFrame from '%s'"), dlg
.GetPath());
664 wxFrame
*trueFrame
= wx_dynamic_cast(wxFrame
*, frame
);
667 wxDynamicObject
* dyno
= wx_dynamic_cast(wxDynamicObject
*, frame
);
669 trueFrame
= wx_dynamic_cast(wxFrame
*, dyno
->GetSuperClassInstance() );
675 wxLogError(wxT("Could not show the frame"));
678 void MyFrame::OnGenerateCode(wxCommandEvent
& WXUNUSED(event
))
680 // ask the user which file to load
681 wxFileDialog
dlg(this, wxT("Which file contains the frame to work on?"),
682 wxEmptyString
, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
684 if (dlg
.ShowModal() == wxID_CANCEL
)
687 // ask the user which file to load
688 wxFileDialog
dlg2(this, wxT("Where should the C++ code be saved?"),
689 wxEmptyString
, wxT("test.cpp"), wxT("Source files (*.cpp)|*.cpp"),
691 if (dlg2
.ShowModal() == wxID_CANCEL
)
695 if (!GenerateFrameRTTICode(dlg
.GetPath(), dlg2
.GetPath()))
697 wxLogError(wxT("Could not generate the code for the frame!"));
701 // show the generated code
703 wxFileInputStream
f(dlg2
.GetPath());
704 wxStringOutputStream str
;
707 wxDialog
dlg(this, wxID_ANY
, wxT("Generated code"),
708 wxDefaultPosition
, wxDefaultSize
,
709 wxRESIZE_BORDER
|wxDEFAULT_DIALOG_STYLE
);
710 wxPanel
*panel
= new wxPanel(&dlg
);
711 wxSizer
*sz
= new wxBoxSizer(wxVERTICAL
);
712 sz
->Add(new wxTextCtrl(panel
, wxID_ANY
, str
.GetString(),
713 wxDefaultPosition
, wxDefaultSize
,
714 wxTE_MULTILINE
|wxTE_READONLY
|wxTE_DONTWRAP
),
716 sz
->Add(new wxButton(panel
, wxID_OK
), 0, wxALIGN_RIGHT
|wxALL
, 5);
717 panel
->SetSizerAndFit(sz
);
722 void MyFrame::OnDumpClasses(wxCommandEvent
& WXUNUSED(event
))
724 ClassListDialog
dlg(this);
728 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
730 // true is to force the frame to close
734 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
736 wxMessageBox(wxString::Format(
737 wxT("Welcome to %s!\n")
739 wxT("This sample demonstrates wxWidgets eXtended RTTI (XTI) system."),
742 wxT("About wxWidgets XTI sample"),
743 wxOK
| wxICON_INFORMATION
,