]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxShadowObject for imitating a VMT with
authorRobert Roebling <robert@roebling.de>
Sun, 26 Jun 2005 15:48:02 +0000 (15:48 +0000)
committerRobert Roebling <robert@roebling.de>
Sun, 26 Jun 2005 15:48:02 +0000 (15:48 +0000)
   virtual functions without changing the C++
   interface etc. of the class.
  Added test to it to the dynamic sample.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@34763 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/clntdata.h
samples/dynamic/dynamic.cpp

index 83cdd0cf4b524dc0d3fd03272f4994fb05e91c54..dd208f111a1c13ae8acdeb33e99a387d1e38b81b 100644 (file)
 
 #include "wx/defs.h"
 #include "wx/string.h"
+#include "wx/hashmap.h"
+
+typedef int (*wxShadowObjectMethod)(void*, void*);
+WX_DECLARE_STRING_HASH_MAP( wxShadowObjectMethod, wxShadowObjectMethods );
+WX_DECLARE_STRING_HASH_MAP( void*, wxShadowObjectFields );
+
+class WXDLLIMPEXP_BASE wxShadowObject
+{
+public:
+    wxShadowObject() { }
+    
+    void AddMethod( const wxString &name, wxShadowObjectMethod method )
+    { 
+        wxShadowObjectMethods::iterator it = m_methods.find( name );
+        if (it == m_methods.end())
+            m_methods[ name ] = method;
+        else
+            it->second = method;
+    }
+    
+    bool InvokeMethod( const wxString &name, void* window, void* param, int* returnValue )
+    { 
+        wxShadowObjectMethods::iterator it = m_methods.find( name );
+        if (it == m_methods.end())
+            return false;
+        wxShadowObjectMethod method = it->second;
+        int ret = (*method)(window, param);
+        if (returnValue)
+            *returnValue = ret;
+        return true;
+    }
+    
+    void AddField( const wxString &name, void* initialValue = NULL )
+    {
+        wxShadowObjectFields::iterator it = m_fields.find( name );
+        if (it == m_fields.end())
+            m_fields[ name ] = initialValue;
+        else
+            it->second = initialValue;
+    }
+    
+    void SetField( const wxString &name, void* value )
+    {
+        wxShadowObjectFields::iterator it = m_fields.find( name );
+        if (it == m_fields.end())
+            return;
+        it->second = value;
+    }
+    
+    void* GetField( const wxString &name, void *defaultValue = NULL )
+    {
+        wxShadowObjectFields::iterator it = m_fields.find( name );
+        if (it == m_fields.end())
+            return defaultValue;
+        return it->second;
+    }
+    
+private:
+    wxShadowObjectMethods   m_methods;
+    wxShadowObjectFields    m_fields;
+};
 
 // ----------------------------------------------------------------------------
 
index f94ca57e44fcd3cd36c5b40ffaac510fa5a79cfd..ea9c0e3d069c39eb701bf1c10de79df52c0c9b18 100644 (file)
 #include "wx/wx.h"
 #endif
 
+#include "wx/clntdata.h"
+
 #if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXCOCOA__)
 #include "mondrian.xpm"
 #endif
 
 // Define a new application type
 class MyApp: public wxApp
-{ public:
+{ 
+public:
     bool OnInit(void);
 };
 
 // Define a new frame type
 class MyFrame: public wxFrame
-{ public:
+{ 
+public:
     MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h);
 
- public:
+public:
     void OnQuit(wxCommandEvent& event);
+    void OnTest(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
+    
+protected:
+    wxShadowObject m_shadow;
+};
+
+// Define another new frame type
+class MySecondFrame: public MyFrame
+{ 
+public:
+    MySecondFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h);
 };
 
 // ID for the menu commands
 #define DYNAMIC_QUIT   wxID_EXIT
-#define DYNAMIC_TEXT   101
+#define DYNAMIC_TEST   101
 #define DYNAMIC_ABOUT  wxID_ABOUT
 
 // Create a new application object
@@ -56,60 +71,110 @@ IMPLEMENT_APP  (MyApp)
 // `Main program' equivalent, creating windows and returning main app frame
 bool MyApp::OnInit(void)
 {
-  // Create the main frame window
-  MyFrame *frame = new MyFrame(NULL, _T("Dynamic wxWidgets App"), 50, 50, 450, 340);
-
-  // You used to have to do some casting for param 4, but now there are type-safe handlers
-  frame->Connect( DYNAMIC_QUIT,  wxID_ANY,
-                    wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyFrame::OnQuit) );
-  frame->Connect( DYNAMIC_ABOUT, wxID_ANY,
-                    wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyFrame::OnAbout) );
-
-  // Give it an icon
-#ifdef __WXMSW__
-  frame->SetIcon(wxIcon(_T("mondrian")));
-#else
-  frame->SetIcon(wxIcon(mondrian_xpm));
-#endif
+    // Create the main frame window
+    MyFrame *frame = new MyFrame(NULL, _T("Dynamic wxWidgets App"), 50, 50, 450, 340);
 
-  // Make a menubar
-  wxMenu *file_menu = new wxMenu;
+    // Show the frame
+    frame->Show(true);
+     
+    // Create the main frame window
+    MySecondFrame *frame2 = new MySecondFrame(NULL, _T("Dynamic wxWidgets App"), 150, 150, 450, 340);
+    
+    // Show the frame
+    frame2->Show(true);
 
-  file_menu->Append(DYNAMIC_ABOUT, _T("&About"));
-  file_menu->Append(DYNAMIC_QUIT, _T("E&xit"));
-  wxMenuBar *menu_bar = new wxMenuBar;
-  menu_bar->Append(file_menu, _T("&File"));
-  frame->SetMenuBar(menu_bar);
+    SetTopWindow(frame);
 
-  // Make a panel with a message
-  wxPanel *panel = new wxPanel(frame, wxID_ANY, wxPoint(0, 0), wxSize(400, 200), wxTAB_TRAVERSAL);
-
-  (void)new wxStaticText(panel, 311, _T("Hello!"), wxPoint(10, 10), wxDefaultSize, 0);
+    return true;
+}
 
-  // Show the frame
-  frame->Show(true);
+// -------------------------------------
+// MyFrame
+// -------------------------------------
 
-  SetTopWindow(frame);
+// Callback from wxShadowObject
 
-  return true;
+int cb_MyFrame_InitStatusbar( void* window, void* param )
+{
+    MyFrame *frame = (MyFrame*) window;
+    frame->SetStatusText( wxT("Hello from MyFrame"), 0 );
+    return 0;
 }
 
 // My frame constructor
 MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
   wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h))
-{}
+{
+    // Give it an icon
+#ifdef __WXMSW__
+    SetIcon(wxIcon(_T("mondrian")));
+#else
+    SetIcon(wxIcon(mondrian_xpm));
+#endif
+
+    // Make a menubar
+    wxMenu *file_menu = new wxMenu;
+
+    file_menu->Append(DYNAMIC_ABOUT, _T("&About"));
+    file_menu->Append(DYNAMIC_TEST, _T("&Test"));
+    file_menu->Append(DYNAMIC_QUIT, _T("E&xit"));
+    wxMenuBar *menu_bar = new wxMenuBar;
+    menu_bar->Append(file_menu, _T("&File"));
+    SetMenuBar(menu_bar);
+
+    // Make a panel with a message
+    wxPanel *panel = new wxPanel(this, wxID_ANY, wxPoint(0, 0), wxSize(400, 200), wxTAB_TRAVERSAL);
+
+    (void)new wxStaticText(panel, 311, _T("Hello!"), wxPoint(10, 10), wxDefaultSize, 0);
+
+    // You used to have to do some casting for param 4, but now there are type-safe handlers
+    Connect( DYNAMIC_QUIT,  wxID_ANY,
+                    wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyFrame::OnQuit) );
+    Connect( DYNAMIC_TEST, wxID_ANY,
+                    wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyFrame::OnTest) );
+    Connect( DYNAMIC_ABOUT, wxID_ANY,
+                    wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyFrame::OnAbout) );
+                    
+    CreateStatusBar();
+    m_shadow.AddMethod( wxT("OnTest"), &cb_MyFrame_InitStatusbar );
+}
 
 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
 {
-  Close(true);
+    Close(true);
+}
+
+void MyFrame::OnTest(wxCommandEvent& WXUNUSED(event) )
+{
+    m_shadow.InvokeMethod( wxT("OnTest"), this, NULL, NULL );
 }
 
 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
 {
-  wxMessageDialog dialog(this, _T("This demonstrates dynamic event handling"),
-    _T("About Dynamic"), wxYES_NO|wxCANCEL);
+    wxMessageDialog dialog(this, _T("This demonstrates dynamic event handling"),
+        _T("About Dynamic"), wxYES_NO|wxCANCEL);
 
-  dialog.ShowModal();
+    dialog.ShowModal();
 }
 
 
+// -------------------------------------
+// MySecondFrame
+// -------------------------------------
+
+// Callback from wxShadowObject
+
+int cb_MySecondFrame_InitStatusbar( void* window, void* param )
+{
+    MySecondFrame *frame = (MySecondFrame*) window;
+    frame->SetStatusText( wxT("Hello from MySecondFrame"), 0 );
+    return 0;
+}
+
+// My frame constructor
+MySecondFrame::MySecondFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
+  MyFrame(frame, title, x, y, w, h )
+{
+    m_shadow.AddMethod( wxT("OnTest"), &cb_MySecondFrame_InitStatusbar );
+}
+