Change {DECLARE,IMPLEMENT}_*CLASS and {DECLARE,BEGIN,END}_EVENT_TABLE
occurrences to use the wx-prefixed version of the macros.
		
	
		
			
				
	
	
		
			746 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			746 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        xti.cpp
 | 
						|
// Purpose:     eXtended RTTI support sample
 | 
						|
// Author:      Stefan Csomor, Francesco Montorsi
 | 
						|
// Modified by:
 | 
						|
// Created:     13/5/2007
 | 
						|
// Copyright:   (c) Stefan Csomor, Francesco Montorsi
 | 
						|
// Licence:     wxWindows licence
 | 
						|
/////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// ============================================================================
 | 
						|
// declarations
 | 
						|
// ============================================================================
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// headers
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// For compilers that support precompilation, includes "wx/wx.h".
 | 
						|
#include "wx/wxprec.h"
 | 
						|
 | 
						|
#ifdef __BORLANDC__
 | 
						|
    #pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
// for all others, include the necessary headers (this file is usually all you
 | 
						|
// need because it includes almost all "standard" wxWidgets headers)
 | 
						|
#ifndef WX_PRECOMP
 | 
						|
    #include "wx/wx.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#include "wx/wx.h"
 | 
						|
#include "wx/variant.h"
 | 
						|
#include "wx/xml/xml.h"
 | 
						|
#include "wx/frame.h"
 | 
						|
#include "wx/notebook.h"
 | 
						|
#include "wx/event.h"
 | 
						|
#include "wx/spinbutt.h"
 | 
						|
#include "wx/spinctrl.h"
 | 
						|
 | 
						|
#include "wx/xtistrm.h"
 | 
						|
#include "wx/xtixml.h"
 | 
						|
#include "wx/txtstrm.h"
 | 
						|
#include "wx/wfstream.h"
 | 
						|
#include "wx/sstream.h"
 | 
						|
#include "wx/spinctrl.h"
 | 
						|
 | 
						|
#include "classlist.h"
 | 
						|
#include "codereadercallback.h"
 | 
						|
 | 
						|
#if !wxUSE_EXTENDED_RTTI
 | 
						|
    #error This sample requires XTI (eXtended RTTI) enabled
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// resources
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
#ifndef wxHAS_IMAGES_IN_RESOURCES
 | 
						|
    #include "../sample.xpm"
 | 
						|
#endif
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// private classes
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// Define a new application type, each program should derive a class from wxApp
 | 
						|
class MyApp : public wxApp
 | 
						|
{
 | 
						|
public:
 | 
						|
    virtual bool OnInit();
 | 
						|
};
 | 
						|
 | 
						|
// Define a new frame type: this is going to be our main frame
 | 
						|
class MyFrame : public wxFrame
 | 
						|
{
 | 
						|
public:
 | 
						|
    // ctor(s)
 | 
						|
    MyFrame(const wxString& title);
 | 
						|
 | 
						|
    void OnPersist(wxCommandEvent& event);
 | 
						|
    void OnDepersist(wxCommandEvent& event);
 | 
						|
    void OnGenerateCode(wxCommandEvent& event);
 | 
						|
    void OnDumpClasses(wxCommandEvent& event);
 | 
						|
    void OnQuit(wxCommandEvent& event);
 | 
						|
    void OnAbout(wxCommandEvent& event);
 | 
						|
 | 
						|
private:
 | 
						|
    // any class wishing to process wxWidgets events must use this macro
 | 
						|
    wxDECLARE_EVENT_TABLE();
 | 
						|
};
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// constants
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// IDs for the controls and the menu commands
 | 
						|
enum
 | 
						|
{
 | 
						|
    // menu items
 | 
						|
    Minimal_Persist = wxID_HIGHEST,
 | 
						|
    Minimal_Depersist,
 | 
						|
    Minimal_GenerateCode,
 | 
						|
    Minimal_DumpClasses,
 | 
						|
    Minimal_Quit = wxID_EXIT,
 | 
						|
    Minimal_About = wxID_ABOUT
 | 
						|
};
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// event tables and other macros for wxWidgets
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
 | 
						|
    EVT_MENU(Minimal_Persist, MyFrame::OnPersist)
 | 
						|
    EVT_MENU(Minimal_Depersist, MyFrame::OnDepersist)
 | 
						|
    EVT_MENU(Minimal_GenerateCode, MyFrame::OnGenerateCode)
 | 
						|
    EVT_MENU(Minimal_DumpClasses, MyFrame::OnDumpClasses)
 | 
						|
    EVT_MENU(Minimal_Quit,  MyFrame::OnQuit)
 | 
						|
    EVT_MENU(Minimal_About, MyFrame::OnAbout)
 | 
						|
wxEND_EVENT_TABLE()
 | 
						|
 | 
						|
wxIMPLEMENT_APP(MyApp);
 | 
						|
 | 
						|
// ============================================================================
 | 
						|
// implementation
 | 
						|
// ============================================================================
 | 
						|
 | 
						|
void RegisterFrameRTTI();
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// the application class
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
bool MyApp::OnInit()
 | 
						|
{
 | 
						|
    if ( !wxApp::OnInit() )
 | 
						|
        return false;
 | 
						|
 | 
						|
    RegisterFrameRTTI();
 | 
						|
 | 
						|
    // create the main application window
 | 
						|
    MyFrame *frame = new MyFrame(wxT("Extended RTTI sample"));
 | 
						|
 | 
						|
    // and show it (the frames, unlike simple controls, are not shown when
 | 
						|
    // created initially)
 | 
						|
    frame->Show(true);
 | 
						|
 | 
						|
    // success: wxApp::OnRun() will be called which will enter the main message
 | 
						|
    // loop and the application will run. If we returned false here, the
 | 
						|
    // application would exit immediately.
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// main frame
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
MyFrame::MyFrame(const wxString& title)
 | 
						|
    : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
 | 
						|
{
 | 
						|
    // set the frame icon
 | 
						|
    SetIcon(wxICON(sample));
 | 
						|
 | 
						|
#if wxUSE_MENUS
 | 
						|
    // create a menu bar
 | 
						|
    wxMenu *fileMenu = new wxMenu;
 | 
						|
 | 
						|
    // the "About" item should be in the help menu
 | 
						|
    wxMenu *helpMenu = new wxMenu;
 | 
						|
    helpMenu->Append(Minimal_About, wxT("&About\tF1"), wxT("Show about dialog"));
 | 
						|
 | 
						|
    fileMenu->Append(Minimal_Persist, wxT("Persist a wxFrame to XML..."), 
 | 
						|
                    wxT("Creates a wxFrame using wxXTI and saves its description as XML"));
 | 
						|
    fileMenu->Append(Minimal_Depersist, wxT("Depersist XML file..."), 
 | 
						|
                    wxT("Loads the description of wxFrame from XML"));
 | 
						|
    fileMenu->Append(Minimal_GenerateCode, wxT("Generate code for a wxFrame saved to XML..."), 
 | 
						|
                    wxT("Generates the C++ code which belong to a persisted wxFrame"));
 | 
						|
    fileMenu->AppendSeparator();
 | 
						|
    fileMenu->Append(Minimal_DumpClasses, wxT("Dump registered classes..."), 
 | 
						|
                    wxT("Dumps the description of all wxWidgets classes registered in XTI"));
 | 
						|
    fileMenu->AppendSeparator();
 | 
						|
    fileMenu->Append(Minimal_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
 | 
						|
 | 
						|
    // now append the freshly created menu to the menu bar...
 | 
						|
    wxMenuBar *menuBar = new wxMenuBar();
 | 
						|
    menuBar->Append(fileMenu, wxT("&File"));
 | 
						|
    menuBar->Append(helpMenu, wxT("&Help"));
 | 
						|
 | 
						|
    // ... and attach this menu bar to the frame
 | 
						|
    SetMenuBar(menuBar);
 | 
						|
#endif // wxUSE_MENUS
 | 
						|
 | 
						|
#if wxUSE_STATUSBAR
 | 
						|
    // create a status bar just for fun (by default with 1 pane only)
 | 
						|
    CreateStatusBar(2);
 | 
						|
    SetStatusText(wxT("Welcome to wxWidgets!"));
 | 
						|
#endif // wxUSE_STATUSBAR
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// XTI sample code
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// this is the kind of source code that would end up being generated by a 
 | 
						|
// designer corresponding to the information we are setting up via RTTI 
 | 
						|
// in the CreateFrameRTTI function:
 | 
						|
//
 | 
						|
//  class MyXTIFrame : public wxFrame
 | 
						|
//  {
 | 
						|
//  public:
 | 
						|
//       //   construction
 | 
						|
//      MyXTIFrame()
 | 
						|
//      {
 | 
						|
//          Init();
 | 
						|
//          m_button = NULL;
 | 
						|
//      }
 | 
						|
//
 | 
						|
//      bool Create(wxWindow *parent,
 | 
						|
//                  wxWindowID id,
 | 
						|
//                  const wxString& title,
 | 
						|
//                  const wxPoint& pos = wxDefaultPosition,
 | 
						|
//                  const wxSize& size = wxDefaultSize,
 | 
						|
//                  long style = wxDEFAULT_FRAME_STYLE,
 | 
						|
//                  const wxString& name = wxFrameNameStr)
 | 
						|
//      {
 | 
						|
//          return wxFrame::Create( parent, id, title, pos, size, style, name );
 | 
						|
//      }
 | 
						|
//
 | 
						|
//      void SetButton( wxButton * button ) { m_button = button; }
 | 
						|
//      wxButton* GetButton() const { return m_button; }
 | 
						|
//
 | 
						|
//      void ButtonClickHandler( wxEvent & WXUNUSED(event) )
 | 
						|
//      {
 | 
						|
//          wxMessageBox( "Button Clicked ", "Hi!", wxOK );
 | 
						|
//      }
 | 
						|
//
 | 
						|
//  protected:
 | 
						|
//      wxButton* m_button;
 | 
						|
//
 | 
						|
//      wxDECLARE_EVENT_TABLE();
 | 
						|
//      wxDECLARE_DYNAMIC_CLASS_NO_COPY(MyXTIFrame);
 | 
						|
//  };
 | 
						|
//
 | 
						|
//  wxIMPLEMENT_DYNAMIC_CLASS_XTI(MyXTIFrame, MyXTIFrame, "x.h");
 | 
						|
//
 | 
						|
//  WX_BEGIN_PROPERTIES_TABLE(MyXTIFrame)
 | 
						|
//      WX_PROPERTY( Button, wxButton*, SetButton, GetButton, )
 | 
						|
//  WX_END_PROPERTIES_TABLE()
 | 
						|
//
 | 
						|
//  WX_BEGIN_HANDLERS_TABLE(MyXTIFrame)
 | 
						|
//      WX_HANDLER( ButtonClickHandler, wxCommandEvent )
 | 
						|
//  WX_END_HANDLERS_TABLE()
 | 
						|
//
 | 
						|
//  WX_CONSTRUCTOR_5( MyXTIFrame, wxWindow*, Parent, wxWindowID, Id,
 | 
						|
//                    wxString, Title, wxPoint, Position, wxSize, Size )
 | 
						|
//
 | 
						|
//  wxBEGIN_EVENT_TABLE(MyXTIFrame, wxFrame)
 | 
						|
//  wxEND_EVENT_TABLE()
 | 
						|
 | 
						|
// the following class "persists" (i.e. saves) a wxFrame into a wxObjectWriter
 | 
						|
 | 
						|
class MyDesignerPersister : public wxObjectWriterCallback
 | 
						|
{
 | 
						|
public:
 | 
						|
    MyDesignerPersister( wxDynamicObject * frame)
 | 
						|
    {
 | 
						|
        m_frame = frame;
 | 
						|
    }
 | 
						|
 | 
						|
    virtual bool BeforeWriteDelegate( wxObjectWriter *WXUNUSED(writer),
 | 
						|
                                    const wxObject *object,  
 | 
						|
                                    const wxClassInfo* WXUNUSED(classInfo), 
 | 
						|
                                    const wxPropertyInfo *propInfo, 
 | 
						|
                                    const wxObject *&eventSink, 
 | 
						|
                                    const wxHandlerInfo* &handlerInfo )  
 | 
						|
    {
 | 
						|
        // this approach would be used if the handler would not 
 | 
						|
        // be connected really in the designer, so we have to supply 
 | 
						|
        // the information
 | 
						|
        const wxObject* but = wxAnyGetAsObjectPtr( m_frame->GetProperty(wxT("Button")) );
 | 
						|
        if ( object == but && 
 | 
						|
             propInfo == wxCLASSINFO( wxButton )->FindPropertyInfo(wxT("OnClick")) )
 | 
						|
        {
 | 
						|
            eventSink = m_frame;
 | 
						|
            handlerInfo = m_frame->GetClassInfo()->
 | 
						|
                FindHandlerInfo(wxT("ButtonClickHandler"));
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
private:
 | 
						|
    wxDynamicObject *m_frame;
 | 
						|
};
 | 
						|
 | 
						|
// sometimes linkers (at least MSVC and GCC ones) optimize the final EXE 
 | 
						|
// even in debug mode pruning the object files which he "thinks" are useless;
 | 
						|
// thus the classes defined in those files won't be available in the XTI
 | 
						|
// table and the program will fail to allocate them.
 | 
						|
// The following macro implements a simple hack to ensure that a given
 | 
						|
// class is linked in.
 | 
						|
//
 | 
						|
// TODO: in wx/link.h there are already similar macros (also more "optimized":
 | 
						|
//       don't need the creation of fake object) which however require to use
 | 
						|
//       the wxFORCE_LINK_THIS_MODULE() macro inside the source files corresponding
 | 
						|
//       to the class being discarded.
 | 
						|
//
 | 
						|
#define wxENSURE_CLASS_IS_LINKED(x)     { x test; }
 | 
						|
 | 
						|
void RegisterFrameRTTI()
 | 
						|
{
 | 
						|
    // set up the RTTI info for a class (MyXTIFrame) which
 | 
						|
    // is not defined anywhere in this program
 | 
						|
    wxDynamicClassInfo *dyninfo = 
 | 
						|
        wx_dynamic_cast( wxDynamicClassInfo *, wxClassInfo::FindClass(wxT("MyXTIFrame")));
 | 
						|
    if ( dyninfo == NULL )
 | 
						|
    {
 | 
						|
        dyninfo = new wxDynamicClassInfo(wxT("myxtiframe.h"),
 | 
						|
                            wxT("MyXTIFrame"), 
 | 
						|
                            CLASSINFO(wxFrame) );
 | 
						|
 | 
						|
        // this class has a property named "Button" and the relative handler:
 | 
						|
        dyninfo->AddProperty(wxT("Button"), wxGetTypeInfo((wxButton**) NULL));
 | 
						|
        dyninfo->AddHandler(wxT("ButtonClickHandler"), 
 | 
						|
            NULL /* no instance of the handler method */, CLASSINFO( wxEvent ) );
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
wxDynamicObject* CreateFrameRTTI()
 | 
						|
{
 | 
						|
    int baseID = 100;
 | 
						|
    wxAny Params[10];
 | 
						|
 | 
						|
    // the class is now part of XTI internal table so that we can
 | 
						|
    // get a pointer to it just searching it like any other class:
 | 
						|
    wxFrame* frame;
 | 
						|
    wxClassInfo *info = wxClassInfo::FindClass(wxT("MyXTIFrame"));
 | 
						|
    wxASSERT( info );
 | 
						|
    wxDynamicObject* frameWrapper = 
 | 
						|
        wx_dynamic_cast(wxDynamicObject*, info->CreateObject() );
 | 
						|
    Params[0] = wxAny((wxWindow*)(NULL));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString(wxT("This is a frame created from XTI")));
 | 
						|
    Params[3] = wxAny(wxPoint(-1,-1));
 | 
						|
    Params[4] = wxAny(wxSize(400,300));
 | 
						|
    Params[5] = wxAny((long)wxDEFAULT_FRAME_STYLE);
 | 
						|
    wxASSERT( info->Create(frameWrapper, 6, Params ));
 | 
						|
    frame = wx_dynamic_cast(wxFrame*, frameWrapper->GetSuperClassInstance());
 | 
						|
 | 
						|
#if 1
 | 
						|
    // now build a notebook inside it:
 | 
						|
    wxNotebook* notebook;
 | 
						|
    info = wxClassInfo::FindClass("wxNotebook");
 | 
						|
    wxASSERT( info );
 | 
						|
    notebook = wxDynamicCast( info->CreateObject(), wxNotebook );
 | 
						|
    Params[0] = wxAny((wxWindow*)frame);
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxPoint( 10, 10 ));
 | 
						|
    Params[3] = wxAny(wxDefaultSize);
 | 
						|
    Params[4] = wxAny((long)0);
 | 
						|
    wxASSERT( info->Create(notebook, 5, Params ));
 | 
						|
 | 
						|
    // button page
 | 
						|
 | 
						|
    wxPanel* panel;
 | 
						|
    info = wxClassInfo::FindClass("wxPanel");
 | 
						|
    wxASSERT( info );
 | 
						|
    panel = wxDynamicCast( info->CreateObject(), wxPanel );
 | 
						|
    Params[0] = wxAny((wxWindow*)(notebook));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxPoint(-1,-1));
 | 
						|
    Params[3] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[4] = wxAny((long)0);
 | 
						|
    Params[5] = wxAny(wxString(wxT("Hello")));
 | 
						|
    wxASSERT( info->Create(panel, 6, Params ));
 | 
						|
    notebook->AddPage( panel, "Buttons" );
 | 
						|
 | 
						|
    wxButton* button;
 | 
						|
    info = wxClassInfo::FindClass("wxButton");
 | 
						|
    wxASSERT( info );
 | 
						|
    button = wxDynamicCast( info->CreateObject(), wxButton );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString(wxT("Click Me!")));
 | 
						|
    Params[3] = wxAny(wxPoint( 10, 10 ));
 | 
						|
    Params[4] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[5] = wxAny((long)0);
 | 
						|
    wxASSERT( info->Create(button, 6, Params ));
 | 
						|
    frameWrapper->SetProperty( wxT("Button"), wxAny( button ) );
 | 
						|
 | 
						|
    // other controls page
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxPanel");
 | 
						|
    wxASSERT( info );
 | 
						|
    panel = wxDynamicCast( info->CreateObject(), wxPanel );
 | 
						|
    Params[0] = wxAny((wxWindow*)(notebook));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxPoint(-1,-1));
 | 
						|
    Params[3] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[4] = wxAny((long)0);
 | 
						|
    Params[5] = wxAny(wxString(wxT("Hello")));
 | 
						|
    wxASSERT( info->Create(panel, 6, Params ));
 | 
						|
    notebook->AddPage( panel, "Other Standard controls" );
 | 
						|
 | 
						|
    wxControl* control;
 | 
						|
    info = wxClassInfo::FindClass("wxCheckBox");
 | 
						|
    wxASSERT( info );
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString(wxT("A Checkbox")));
 | 
						|
    Params[3] = wxAny(wxPoint( 10, 10 ));
 | 
						|
    Params[4] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[5] = wxAny((long)0);
 | 
						|
    wxASSERT( info->Create(control, 6, Params ));
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxRadioButton");
 | 
						|
    wxASSERT( info );
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString(wxT("A Radiobutton")));
 | 
						|
    Params[3] = wxAny(wxPoint( 10, 30 ));
 | 
						|
    Params[4] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[5] = wxAny((long)0);
 | 
						|
    wxASSERT( info->Create(control, 6, Params ));
 | 
						|
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString(wxT("Another One")));
 | 
						|
    Params[3] = wxAny(wxPoint( 10, 50 ));
 | 
						|
    wxASSERT( info->Create(control, 6, Params ));
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxStaticText");
 | 
						|
    wxASSERT( info );
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString(wxT("A Static Text!")));
 | 
						|
    Params[3] = wxAny(wxPoint( 10, 70 ));
 | 
						|
    Params[4] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[5] = wxAny((long)0);
 | 
						|
    wxASSERT( info->Create(control, 6, Params ));
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxStaticBox");
 | 
						|
    wxASSERT( info );
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString(wxT("A Static Box")));
 | 
						|
    Params[3] = wxAny(wxPoint( 10, 90 ));
 | 
						|
    Params[4] = wxAny(wxSize(100,80));
 | 
						|
    Params[5] = wxAny((long)0);
 | 
						|
    wxASSERT( info->Create(control, 6, Params ));
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxTextCtrl");
 | 
						|
    wxASSERT( info );
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString(wxT("A Text Control")));
 | 
						|
    Params[3] = wxAny(wxPoint( 10, 200 ));
 | 
						|
    Params[4] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[5] = wxAny((long)0);
 | 
						|
    wxASSERT( info->Create(control, 6, Params ));
 | 
						|
 | 
						|
    // spins and gauges page
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxPanel");
 | 
						|
    wxASSERT( info );
 | 
						|
    panel = wxDynamicCast( info->CreateObject(), wxPanel );
 | 
						|
    Params[0] = wxAny((wxWindow*)(notebook));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxPoint(-1,-1));
 | 
						|
    Params[3] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[4] = wxAny((long)0);
 | 
						|
    Params[5] = wxAny(wxString(wxT("Hello")));
 | 
						|
    wxASSERT( info->Create(panel, 6, Params ));
 | 
						|
    notebook->AddPage( panel, "Spins and Sliders" );
 | 
						|
 | 
						|
    wxENSURE_CLASS_IS_LINKED(wxSpinButton);
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxSpinButton");
 | 
						|
    wxASSERT( info );
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxPoint( 10, 10 ));
 | 
						|
    Params[3] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[4] = wxAny((long)wxSP_VERTICAL | wxSP_ARROW_KEYS);
 | 
						|
    wxASSERT( info->Create(control, 5, Params ));
 | 
						|
 | 
						|
    wxENSURE_CLASS_IS_LINKED(wxSpinCtrl);
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxSpinCtrl");
 | 
						|
    wxASSERT( info );
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny(wxString("20"));
 | 
						|
    Params[3] = wxAny(wxPoint( 40, 10 ));
 | 
						|
    Params[4] = wxAny(wxSize(40,-1));
 | 
						|
    Params[5] = wxAny((long) wxSP_ARROW_KEYS);
 | 
						|
    wxASSERT( info->Create(control, 6, Params ));
 | 
						|
 | 
						|
    // MSVC likes to exclude from link wxGauge...
 | 
						|
    wxENSURE_CLASS_IS_LINKED(wxGauge)
 | 
						|
    wxENSURE_CLASS_IS_LINKED(wxCheckBox)
 | 
						|
    wxENSURE_CLASS_IS_LINKED(wxSpinCtrl)
 | 
						|
 | 
						|
    info = wxClassInfo::FindClass("wxGauge");
 | 
						|
 | 
						|
    wxASSERT( info );
 | 
						|
    control = wxDynamicCast( info->CreateObject(), wxControl );
 | 
						|
    Params[0] = wxAny((wxWindow*)(panel));
 | 
						|
    Params[1] = wxAny(wxWindowID(baseID++));
 | 
						|
    Params[2] = wxAny((int) 100);
 | 
						|
    Params[3] = wxAny(wxPoint( 10, 50 ));
 | 
						|
    Params[4] = wxAny(wxSize(-1,-1));
 | 
						|
    Params[5] = wxAny((long) wxGA_HORIZONTAL);
 | 
						|
    wxASSERT( info->Create(control, 6, Params ));
 | 
						|
    wx_dynamic_cast(wxGauge*, control)->SetValue(20);
 | 
						|
 | 
						|
#endif
 | 
						|
    return frameWrapper;
 | 
						|
}
 | 
						|
 | 
						|
bool SaveFrameRTTI(const wxString &testFileName, wxDynamicObject *frame)
 | 
						|
{
 | 
						|
    // setup the XML document
 | 
						|
    wxXmlDocument xml;
 | 
						|
    wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE, 
 | 
						|
                                    "TestXTI", "This is the content");
 | 
						|
    xml.SetRoot(root);
 | 
						|
 | 
						|
    // setup the XTI writer and persister
 | 
						|
    wxObjectXmlWriter writer(root);
 | 
						|
    MyDesignerPersister persister(frame);
 | 
						|
 | 
						|
    // write the given wxObject into the XML document
 | 
						|
    wxStringToAnyHashMap empty;
 | 
						|
    writer.WriteObject( frame, frame->GetClassInfo(), &persister, 
 | 
						|
                        wxString("myTestFrame"), empty );
 | 
						|
 | 
						|
    return xml.Save(testFileName);
 | 
						|
}
 | 
						|
 | 
						|
wxDynamicObject* LoadFrameRTTI(const wxString &fileName)
 | 
						|
{
 | 
						|
    // load the XML document
 | 
						|
    wxXmlDocument xml;
 | 
						|
    if (!xml.Load(fileName))
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    wxXmlNode *root = xml.GetRoot();
 | 
						|
    if (root->GetName() != "TestXTI")
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    // now depersist the wxFrame we saved into it using wxObjectRuntimeReaderCallback
 | 
						|
    wxObjectRuntimeReaderCallback Callbacks;
 | 
						|
    wxObjectXmlReader Reader( root );
 | 
						|
    int obj = Reader.ReadObject( wxString("myTestFrame"), &Callbacks );
 | 
						|
    return (wxDynamicObject*)Callbacks.GetObject( obj );
 | 
						|
}
 | 
						|
 | 
						|
bool GenerateFrameRTTICode(const wxString &inFileName, const wxString &outFileName)
 | 
						|
{
 | 
						|
    // is loading the streamed out component from xml and writing code that  
 | 
						|
    // will create the same component 
 | 
						|
 | 
						|
    wxFFileOutputStream fos( outFileName );
 | 
						|
    wxTextOutputStream tos( fos );
 | 
						|
    if (!fos.IsOk())
 | 
						|
        return false;
 | 
						|
 | 
						|
    wxXmlDocument xml;
 | 
						|
    if (!xml.Load(inFileName))
 | 
						|
        return false;
 | 
						|
 | 
						|
    wxXmlNode *root = xml.GetRoot();
 | 
						|
    if (root->GetName() != "TestXTI")
 | 
						|
        return false;
 | 
						|
 | 
						|
    // read the XML file using the wxObjectCodeReaderCallback
 | 
						|
    
 | 
						|
    wxString headerincludes;
 | 
						|
    wxString sourcecode;
 | 
						|
    wxObjectCodeReaderCallback Callbacks(headerincludes,sourcecode);
 | 
						|
    wxObjectXmlReader Reader(root);
 | 
						|
 | 
						|
    // ReadObject will return the ID of the object read??
 | 
						|
    Reader.ReadObject( wxString("myTestFrame"), &Callbacks );
 | 
						|
 | 
						|
    // header preamble
 | 
						|
    tos << 
 | 
						|
        "#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";
 | 
						|
    // add object includes
 | 
						|
    tos.WriteString( headerincludes );
 | 
						|
 | 
						|
    tos << "\n\nvoid test()\n{";
 | 
						|
    tos.WriteString( sourcecode );
 | 
						|
    tos << "}";
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// MyFrame event handlers
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
void MyFrame::OnPersist(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    // first create a frame using XTI calls
 | 
						|
    wxDynamicObject *frame = CreateFrameRTTI();
 | 
						|
    if (!frame)
 | 
						|
    {
 | 
						|
        wxLogError(wxT("Cannot create the XTI frame!"));
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    // show the frame we're going to save to the user
 | 
						|
    wxFrame *trueFrame = wx_dynamic_cast(wxFrame *, frame->GetSuperClassInstance() );
 | 
						|
    trueFrame->Show();
 | 
						|
 | 
						|
    // ask the user where to save it
 | 
						|
    wxFileDialog dlg(this, wxT("Where should the frame be saved?"),
 | 
						|
                     wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"), 
 | 
						|
                     wxFD_SAVE);
 | 
						|
    if (dlg.ShowModal() == wxID_CANCEL)
 | 
						|
        return;
 | 
						|
 | 
						|
    // then save it to a test XML file
 | 
						|
    if (!SaveFrameRTTI(dlg.GetPath(), frame))
 | 
						|
    {
 | 
						|
        wxLogError(wxT("Cannot save the XTI frame into '%s'"), dlg.GetPath());
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    // now simply delete it
 | 
						|
    delete frame;
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnDepersist(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    // ask the user which file to load
 | 
						|
    wxFileDialog dlg(this, wxT("Which file contains the frame to depersist?"),
 | 
						|
                     wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"), 
 | 
						|
                     wxFD_OPEN);
 | 
						|
    if (dlg.ShowModal() == wxID_CANCEL)
 | 
						|
        return;
 | 
						|
 | 
						|
    wxObject *frame = LoadFrameRTTI(dlg.GetPath());
 | 
						|
    if (!frame)
 | 
						|
    {
 | 
						|
        wxLogError(wxT("Could not depersist the wxFrame from '%s'"), dlg.GetPath());
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    wxFrame *trueFrame = wx_dynamic_cast(wxFrame*, frame );
 | 
						|
    if ( !trueFrame )
 | 
						|
    {
 | 
						|
        wxDynamicObject* dyno = wx_dynamic_cast(wxDynamicObject*, frame );
 | 
						|
        if ( dyno )
 | 
						|
            trueFrame = wx_dynamic_cast(wxFrame *, dyno->GetSuperClassInstance() );
 | 
						|
    }
 | 
						|
 | 
						|
    if ( trueFrame )
 | 
						|
        trueFrame->Show();
 | 
						|
    else
 | 
						|
        wxLogError(wxT("Could not show the frame"));
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnGenerateCode(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    // ask the user which file to load
 | 
						|
    wxFileDialog dlg(this, wxT("Which file contains the frame to work on?"),
 | 
						|
                     wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"), 
 | 
						|
                     wxFD_OPEN);
 | 
						|
    if (dlg.ShowModal() == wxID_CANCEL)
 | 
						|
        return;
 | 
						|
 | 
						|
    // ask the user which file to load
 | 
						|
    wxFileDialog dlg2(this, wxT("Where should the C++ code be saved?"),
 | 
						|
                      wxEmptyString, wxT("test.cpp"), wxT("Source files (*.cpp)|*.cpp"), 
 | 
						|
                      wxFD_SAVE);
 | 
						|
    if (dlg2.ShowModal() == wxID_CANCEL)
 | 
						|
        return;
 | 
						|
 | 
						|
    // do generate code
 | 
						|
    if (!GenerateFrameRTTICode(dlg.GetPath(), dlg2.GetPath()))
 | 
						|
    {
 | 
						|
        wxLogError(wxT("Could not generate the code for the frame!"));
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    // show the generated code
 | 
						|
    {
 | 
						|
        wxFileInputStream f(dlg2.GetPath());
 | 
						|
        wxStringOutputStream str;
 | 
						|
        f.Read(str);
 | 
						|
 | 
						|
        wxDialog dlg(this, wxID_ANY, wxT("Generated code"), 
 | 
						|
                     wxDefaultPosition, wxDefaultSize,
 | 
						|
                     wxRESIZE_BORDER|wxDEFAULT_DIALOG_STYLE);
 | 
						|
        wxPanel *panel = new wxPanel(&dlg);
 | 
						|
        wxSizer *sz = new wxBoxSizer(wxVERTICAL);
 | 
						|
        sz->Add(new wxTextCtrl(panel, wxID_ANY, str.GetString(), 
 | 
						|
                               wxDefaultPosition, wxDefaultSize, 
 | 
						|
                               wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP),
 | 
						|
                1, wxGROW|wxALL, 5);
 | 
						|
        sz->Add(new wxButton(panel, wxID_OK), 0, wxALIGN_RIGHT|wxALL, 5);
 | 
						|
        panel->SetSizerAndFit(sz);
 | 
						|
        dlg.ShowModal();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnDumpClasses(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    ClassListDialog dlg(this);
 | 
						|
    dlg.ShowModal();
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    // true is to force the frame to close
 | 
						|
    Close(true);
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    wxMessageBox(wxString::Format(
 | 
						|
                    wxT("Welcome to %s!\n")
 | 
						|
                    wxT("\n")
 | 
						|
                    wxT("This sample demonstrates wxWidgets eXtended RTTI (XTI) system."),
 | 
						|
                    wxVERSION_STRING
 | 
						|
                ),
 | 
						|
                wxT("About wxWidgets XTI sample"),
 | 
						|
                wxOK | wxICON_INFORMATION,
 | 
						|
                this);
 | 
						|
}
 |