home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / samples / event / event.cpp next >
C/C++ Source or Header  |  2002-09-01  |  13KB  |  384 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        event.cpp
  3. // Purpose:     wxWindows sample demonstrating different event usage
  4. // Author:      Vadim Zeitlin
  5. // Modified by:
  6. // Created:     31.01.01
  7. // RCS-ID:      $Id: event.cpp,v 1.6 2002/08/31 22:30:49 GD Exp $
  8. // Copyright:   (c) 2001 Vadim Zeitlin
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #if defined(__GNUG__) && !defined(__APPLE__)
  21.     // DO NOT use event.cpp here, it breaks statics initialization in
  22.     // src/common/event.cpp and nothing works at all then!
  23.     #pragma implementation "eventsample.cpp"
  24.     #pragma interface "eventsample.cpp"
  25. #endif
  26.  
  27. // For compilers that support precompilation, includes "wx/wx.h".
  28. #include "wx/wxprec.h"
  29.  
  30. #ifdef __BORLANDC__
  31.     #pragma hdrstop
  32. #endif
  33.  
  34. // for all others, include the necessary headers (this file is usually all you
  35. // need because it includes almost all "standard" wxWindows headers)
  36. #ifndef WX_PRECOMP
  37.     #include "wx/wx.h"
  38. #endif
  39.  
  40. // ----------------------------------------------------------------------------
  41. // event constants
  42. // ----------------------------------------------------------------------------
  43.  
  44. // declare a custom event type
  45. //
  46. // note that in wxWin 2.3+ these macros expand simply into the following code:
  47. //
  48. //  extern const wxEventType wxEVT_MY_CUSTOM_COMMAND;
  49. //
  50. //  const wxEventType wxEVT_MY_CUSTOM_COMMAND = wxNewEventType();
  51. //
  52. // and you may use this code directly if you don't care about 2.2 compatibility
  53. BEGIN_DECLARE_EVENT_TYPES()
  54.     DECLARE_EVENT_TYPE(wxEVT_MY_CUSTOM_COMMAND, 7777)
  55. END_DECLARE_EVENT_TYPES()
  56.  
  57. DEFINE_EVENT_TYPE(wxEVT_MY_CUSTOM_COMMAND)
  58.  
  59. // it may also be convenient to define an event table macro for this event type
  60. #define EVT_MY_CUSTOM_COMMAND(id, fn) \
  61.     DECLARE_EVENT_TABLE_ENTRY( \
  62.         wxEVT_MY_CUSTOM_COMMAND, id, -1, \
  63.         (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)&fn, \
  64.         (wxObject *) NULL \
  65.     ),
  66.  
  67. // ----------------------------------------------------------------------------
  68. // private classes
  69. // ----------------------------------------------------------------------------
  70.  
  71. // Define a new application type, each program should derive a class from wxApp
  72. class MyApp : public wxApp
  73. {
  74. public:
  75.     // override base class virtuals
  76.     // ----------------------------
  77.  
  78.     // this one is called on application startup and is a good place for the app
  79.     // initialization (doing it here and not in the ctor allows to have an error
  80.     // return: if OnInit() returns false, the application terminates)
  81.     virtual bool OnInit();
  82. };
  83.  
  84. // Define a new frame type: this is going to be our main frame
  85. class MyFrame : public wxFrame
  86. {
  87. public:
  88.     // ctor(s)
  89.     MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
  90.     virtual ~MyFrame();
  91.  
  92.     void OnQuit(wxCommandEvent& event);
  93.     void OnAbout(wxCommandEvent& event);
  94.     void OnConnect(wxCommandEvent& event);
  95.     void OnDynamic(wxCommandEvent& event);
  96.     void OnPushEventHandler(wxCommandEvent& event);
  97.     void OnPopEventHandler(wxCommandEvent& event);
  98.     void OnTest(wxCommandEvent& event);
  99.  
  100.     void OnFireCustom(wxCommandEvent& event);
  101.     void OnProcessCustom(wxCommandEvent& event);
  102.  
  103.     void OnUpdateUIPop(wxUpdateUIEvent& event);
  104.  
  105. protected:
  106.     // number of pushed event handlers
  107.     size_t m_nPush;
  108.  
  109. private:
  110.     // any class wishing to process wxWindows events must use this macro
  111.     DECLARE_EVENT_TABLE()
  112. };
  113.  
  114. // Define a custom event handler
  115. class MyEvtHandler : public wxEvtHandler
  116. {
  117. public:
  118.     MyEvtHandler(size_t level) { m_level = level; }
  119.  
  120.     void OnTest(wxCommandEvent& event)
  121.     {
  122.         wxLogMessage(_T("This is the pushed test event handler #%u"), m_level);
  123.  
  124.         // if we don't skip the event, the other event handlers won't get it:
  125.         // try commenting out this line and see what changes
  126.         event.Skip();
  127.     }
  128.  
  129. private:
  130.     size_t m_level;
  131.  
  132.     DECLARE_EVENT_TABLE()
  133. };
  134.  
  135. // ----------------------------------------------------------------------------
  136. // constants
  137. // ----------------------------------------------------------------------------
  138.  
  139. // IDs for the controls and the menu commands
  140. enum
  141. {
  142.     // menu items
  143.     Event_Quit = 1,
  144.     Event_About,
  145.     Event_Connect,
  146.     Event_Dynamic,
  147.     Event_Push,
  148.     Event_Pop,
  149.     Event_Custom,
  150.     Event_Test
  151. };
  152.  
  153. // status bar fields
  154. enum
  155. {
  156.     Status_Main = 0,
  157.     Status_Dynamic,
  158.     Status_Push
  159. };
  160.  
  161. // ----------------------------------------------------------------------------
  162. // event tables and other macros for wxWindows
  163. // ----------------------------------------------------------------------------
  164.  
  165. // the event tables connect the wxWindows events with the functions (event
  166. // handlers) which process them. It can be also done at run-time, but for the
  167. // simple menu events like this the static method is much simpler.
  168. BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  169.     EVT_MENU(Event_Quit,  MyFrame::OnQuit)
  170.     EVT_MENU(Event_About, MyFrame::OnAbout)
  171.  
  172.     EVT_MENU(Event_Connect, MyFrame::OnConnect)
  173.  
  174.     EVT_MENU(Event_Custom, MyFrame::OnFireCustom)
  175.     EVT_MENU(Event_Test, MyFrame::OnTest)
  176.     EVT_MENU(Event_Push, MyFrame::OnPushEventHandler)
  177.     EVT_MENU(Event_Pop, MyFrame::OnPopEventHandler)
  178.  
  179.     EVT_UPDATE_UI(Event_Pop, MyFrame::OnUpdateUIPop)
  180.  
  181.     EVT_MY_CUSTOM_COMMAND(-1, MyFrame::OnProcessCustom)
  182.  
  183.     // this would also work:
  184.     //EVT_CUSTOM(wxEVT_MY_CUSTOM_COMMAND, -1, MyFrame::OnProcessCustom)
  185. END_EVENT_TABLE()
  186.  
  187. BEGIN_EVENT_TABLE(MyEvtHandler, wxEvtHandler)
  188.     EVT_MENU(Event_Test, MyEvtHandler::OnTest)
  189. END_EVENT_TABLE()
  190.  
  191. // Create a new application object: this macro will allow wxWindows to create
  192. // the application object during program execution (it's better than using a
  193. // static object for many reasons) and also declares the accessor function
  194. // wxGetApp() which will return the reference of the right type (i.e. MyApp and
  195. // not wxApp)
  196. IMPLEMENT_APP(MyApp)
  197.  
  198. // ============================================================================
  199. // implementation
  200. // ============================================================================
  201.  
  202. // ----------------------------------------------------------------------------
  203. // the application class
  204. // ----------------------------------------------------------------------------
  205.  
  206. // 'Main program' equivalent: the program execution "starts" here
  207. bool MyApp::OnInit()
  208. {
  209.     // create the main application window
  210.     MyFrame *frame = new MyFrame(_T("Event wxWindows Sample"),
  211.                                  wxPoint(50, 50), wxSize(600, 340));
  212.  
  213.     // and show it (the frames, unlike simple controls, are not shown when
  214.     // created initially)
  215.     frame->Show(TRUE);
  216.  
  217.     // success: wxApp::OnRun() will be called which will enter the main message
  218.     // loop and the application will run. If we returned FALSE here, the
  219.     // application would exit immediately.
  220.     return TRUE;
  221. }
  222.  
  223. // ----------------------------------------------------------------------------
  224. // main frame
  225. // ----------------------------------------------------------------------------
  226.  
  227. // frame constructor
  228. MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
  229.        : wxFrame((wxFrame *)NULL, -1, title, pos, size)
  230. {
  231.     // init members
  232.     m_nPush = 0;
  233.  
  234.     // create a menu bar
  235.     wxMenu *menuFile = new wxMenu;
  236.  
  237.     menuFile->Append(Event_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
  238.     menuFile->AppendSeparator();
  239.     menuFile->Append(Event_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
  240.  
  241.     wxMenu *menuEvent = new wxMenu;
  242.     menuEvent->Append(Event_Connect, _T("&Connect\tCtrl-C"),
  243.                      _T("Connect or disconnect the dynamic event handler"),
  244.                      TRUE /* checkable */);
  245.     menuEvent->Append(Event_Dynamic, _T("&Dynamic event\tCtrl-D"),
  246.                       _T("Dynamic event sample - only works after Connect"));
  247.     menuEvent->AppendSeparator();
  248.     menuEvent->Append(Event_Push, _T("&Push event handler\tCtrl-P"),
  249.                       _T("Push event handler for test event"));
  250.     menuEvent->Append(Event_Pop, _T("P&op event handler\tCtrl-O"),
  251.                       _T("Pop event handler for test event"));
  252.     menuEvent->Append(Event_Test, _T("Test event\tCtrl-T"),
  253.                       _T("Test event processed by pushed event handler"));
  254.     menuEvent->AppendSeparator();
  255.     menuEvent->Append(Event_Custom, _T("Fire c&ustom event\tCtrl-U"),
  256.                       _T("Generate a custom event"));
  257.  
  258.     // now append the freshly created menu to the menu bar...
  259.     wxMenuBar *menuBar = new wxMenuBar();
  260.     menuBar->Append(menuFile, _T("&File"));
  261.     menuBar->Append(menuEvent, _T("&Event"));
  262.  
  263.     // ... and attach this menu bar to the frame
  264.     SetMenuBar(menuBar);
  265.  
  266. #if wxUSE_STATUSBAR
  267.     CreateStatusBar(3);
  268.     SetStatusText(_T("Welcome to wxWindows event sample"));
  269.     SetStatusText(_T("Dynamic: off"), Status_Dynamic);
  270.     SetStatusText(_T("Push count: 0"), Status_Push);
  271. #endif // wxUSE_STATUSBAR
  272. }
  273.  
  274. MyFrame::~MyFrame()
  275. {
  276.     // we must pop any remaining event handlers to avoid memory leaks and
  277.     // crashes!
  278.     while ( m_nPush-- != 0 )
  279.     {
  280.         PopEventHandler(TRUE /* delete handler */);
  281.     }
  282. }
  283.  
  284. // ----------------------------------------------------------------------------
  285. // standard event handlers
  286. // ----------------------------------------------------------------------------
  287.  
  288. void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
  289. {
  290.     // TRUE is to force the frame to close
  291.     Close(TRUE);
  292. }
  293.  
  294. void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
  295. {
  296.     wxMessageBox( wxT("Event sample shows different ways of using events\n")
  297.                   wxT("⌐ 2001 Vadim Zeitlin"),
  298.                   wxT("About Event Sample"), wxOK | wxICON_INFORMATION, this );
  299. }
  300.  
  301. // ----------------------------------------------------------------------------
  302. // dynamic event handling stuff
  303. // ----------------------------------------------------------------------------
  304.  
  305. void MyFrame::OnDynamic(wxCommandEvent& WXUNUSED(event))
  306. {
  307.     wxMessageBox
  308.     (
  309.         wxT("This is a dynamic event handler which can be connected ")
  310.         wxT("and disconnected at run-time."),
  311.         wxT("Dynamic Event Handler"), wxOK | wxICON_INFORMATION, this
  312.     );
  313. }
  314.  
  315. void MyFrame::OnConnect(wxCommandEvent& event)
  316. {
  317.     if ( event.IsChecked() )
  318.     {
  319.         // disconnect
  320.         Connect(Event_Dynamic, -1, wxEVT_COMMAND_MENU_SELECTED,
  321.                 (wxObjectEventFunction)
  322.                 (wxEventFunction)
  323.                 (wxCommandEventFunction)&MyFrame::OnDynamic);
  324.  
  325.         SetStatusText(_T("You can now use \"Dynamic\" item in the menu"));
  326.         SetStatusText(_T("Dynamic: on"), Status_Dynamic);
  327.     }
  328.     else // connect
  329.     {
  330.         Disconnect(Event_Dynamic, -1, wxEVT_COMMAND_MENU_SELECTED);
  331.  
  332.         SetStatusText(_T("You can no more use \"Dynamic\" item in the menu"));
  333.         SetStatusText(_T("Dynamic: off"), Status_Dynamic);
  334.     }
  335. }
  336.  
  337. // ----------------------------------------------------------------------------
  338. // push/pop event handlers support
  339. // ----------------------------------------------------------------------------
  340.  
  341. void MyFrame::OnPushEventHandler(wxCommandEvent& WXUNUSED(event))
  342. {
  343.     PushEventHandler(new MyEvtHandler(++m_nPush));
  344.  
  345.     SetStatusText(wxString::Format(_T("Push count: %u"), m_nPush), Status_Push);
  346. }
  347.  
  348. void MyFrame::OnPopEventHandler(wxCommandEvent& WXUNUSED(event))
  349. {
  350.     wxCHECK_RET( m_nPush, _T("this command should be disabled!") );
  351.  
  352.     PopEventHandler(TRUE /* delete handler */);
  353.     m_nPush--;
  354.  
  355.     SetStatusText(wxString::Format(_T("Push count: %u"), m_nPush), Status_Push);
  356. }
  357.  
  358. void MyFrame::OnTest(wxCommandEvent& event)
  359. {
  360.     wxLogMessage(_T("This is the test event handler in the main frame"));
  361. }
  362.  
  363. void MyFrame::OnUpdateUIPop(wxUpdateUIEvent& event)
  364. {
  365.     event.Enable( m_nPush > 0 );
  366. }
  367.  
  368. // ----------------------------------------------------------------------------
  369. // custom event methods
  370. // ----------------------------------------------------------------------------
  371.  
  372. void MyFrame::OnFireCustom(wxCommandEvent& event)
  373. {
  374.     wxCommandEvent eventCustom(wxEVT_MY_CUSTOM_COMMAND);
  375.  
  376.     wxPostEvent(this, eventCustom);
  377. }
  378.  
  379. void MyFrame::OnProcessCustom(wxCommandEvent& event)
  380. {
  381.     wxLogMessage(_T("Got a custom event!"));
  382. }
  383.  
  384.