]> git.saurik.com Git - wxWidgets.git/commitdiff
update custom event definition documentation; document wxDEFINE/DECLARE_EVENT()
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 7 Feb 2009 16:07:59 +0000 (16:07 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 7 Feb 2009 16:07:59 +0000 (16:07 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58715 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/doxygen/overviews/eventhandling.h
interface/wx/event.h

index f4ecda8f888844fe009e989b4515dbb0b9e07446..0e4c7f2392cd26e1b9783efed49a43c0c3091c59 100644 (file)
@@ -478,170 +478,152 @@ all events (or any selection of them) to the parent window.
 \r
 @subsection overview_events_custom_general General approach\r
 \r
-Since version 2.2.x of wxWidgets, each event type is identified by an ID\r
-given to the event type @e at runtime that makes it possible to add\r
-new event types to the library or application without risking ID clashes\r
-(two different event types mistakingly getting the same event ID).\r
-This event type ID is stored in a struct of type <b>const wxEventType</b>.\r
+As each event is uniquely defined by its event type, defining a custom event\r
+starts with defining a new event type for it. This is done using\r
+wxDEFINE_EVENT() macro. As an event type is a variable, it can also be\r
+declared using wxDECLARE_EVENT() if necessary.\r
 \r
-In order to define a new event type, there are principally two choices.\r
-One is to define an entirely new event class (typically deriving from\r
-wxEvent or wxCommandEvent).\r
-\r
-The other is to use the existing event classes and give them a new event\r
-type. You'll have to define and declare a new event type either way\r
-using the following macros:\r
-\r
-@code\r
-// in the header of the source file\r
-extern const wxEventType wxEVT_YOUR_EVENT_NAME;\r
-\r
-// in the implementation\r
-DEFINE_EVENT_TYPE(wxEVT_YOUR_EVENT_NAME)\r
-@endcode\r
-\r
-See also the @ref page_samples_event for an example of code\r
-defining and working with the custom event types.\r
+The next thing to do is to decide whether you need to define a custom event\r
+class for events of this type or if you can reuse an existing class, typically\r
+either wxEvent (which doesn't provide any extra information) or wxCommandEvent\r
+(which contains several extra fields and also propagates upwards by default).\r
+Both strategies are described in details below. See also the @ref\r
+page_samples_event for a complete example of code defining and working with the\r
+custom event types.\r
 \r
 \r
 @subsection overview_events_custom_existing Using Existing Event Classes\r
 \r
-If you just want to use a wxCommandEvent with a new event type, use\r
-one of the generic event table macros listed below, without having to define a\r
-new event class yourself. This also has the advantage that you won't have to define a\r
-new wxEvent::Clone() method for posting events between threads etc.\r
+If you just want to use a wxCommandEvent with a new event type, use one of the\r
+generic event table macros listed below, without having to define a new event\r
+class yourself.\r
 \r
 Example:\r
 \r
 @code\r
-extern const wxEventType wxEVT_MY_EVENT;\r
-DEFINE_EVENT_TYPE(wxEVT_MY_EVENT)\r
+// this is typically in a header: it just declares MY_EVENT event type\r
+wxDECLARE_EVENT(MY_EVENT, wxCommandEvent);\r
 \r
-// user code intercepting the event\r
+// this is a definition so can't be in a header\r
+wxDEFINE_EVENT(MY_EVENT, wxCommandEvent);\r
 \r
+// example of code handling the event with event tables\r
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)\r
-EVT_MENU    (wxID_EXIT, MyFrame::OnExit)\r
-// ....\r
-EVT_COMMAND (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent)\r
+    EVT_MENU    (wxID_EXIT, MyFrame::OnExit)\r
+    ...\r
+    EVT_COMMAND (ID_MY_WINDOW, MY_EVENT, MyFrame::OnMyEvent)\r
 END_EVENT_TABLE()\r
 \r
-void MyFrame::OnMyEvent( wxCommandEvent& event )\r
+void MyFrame::OnMyEvent(wxCommandEvent& event)\r
 {\r
     // do something\r
     wxString text = event.GetText();\r
 }\r
 \r
+// example of code handling the event with Connect():\r
+MyFrame::MyFrame()\r
+{\r
+    Connect(ID_MY_WINDOW, MY_EVENT, &MyFrame::OnMyEvent);\r
+}\r
 \r
-// user code sending the event\r
-\r
+// example of code generating the event\r
 void MyWindow::SendEvent()\r
 {\r
-    wxCommandEvent event( wxEVT_MY_EVENT, GetId() );\r
-    event.SetEventObject( this );\r
+    wxCommandEvent event(MY_EVENT, GetId());\r
+    event.SetEventObject(this);\r
 \r
     // Give it some contents\r
-    event.SetText( wxT("Hallo") );\r
+    event.SetText("Hello");\r
 \r
-    // Send it\r
-    GetEventHandler()->ProcessEvent( event );\r
+    // Do send it\r
+    ProcessWindowEvent(event);\r
 }\r
 @endcode\r
 \r
 \r
-@subsection overview_events_custom_generic Generic Event Table Macros\r
-\r
-@beginTable\r
-@row2col{EVT_CUSTOM(event\, id\, func),\r
-        Allows you to add a custom event table\r
-        entry by specifying the event identifier (such as wxEVT_SIZE),\r
-        the window identifier, and a member function to call.}\r
-@row2col{EVT_CUSTOM_RANGE(event\, id1\, id2\, func),\r
-        The same as EVT_CUSTOM, but responds to a range of window identifiers.}\r
-@row2col{EVT_COMMAND(id\, event\, func),\r
-        The same as EVT_CUSTOM, but expects a member function with a\r
-        wxCommandEvent argument.}\r
-@row2col{EVT_COMMAND_RANGE(id1\, id2\, event\, func),\r
-        The same as EVT_CUSTOM_RANGE, but\r
-        expects a member function with a wxCommandEvent argument.}\r
-@row2col{EVT_NOTIFY(event\, id\, func),\r
-        The same as EVT_CUSTOM, but\r
-        expects a member function with a wxNotifyEvent argument.}\r
-@row2col{EVT_NOTIFY_RANGE(event\, id1\, id2\, func),\r
-        The same as EVT_CUSTOM_RANGE, but\r
-        expects a member function with a wxNotifyEvent argument.}\r
-@endTable\r
-\r
-\r
 @subsection overview_events_custom_ownclass Defining Your Own Event Class\r
 \r
-Under certain circumstances, you must define your own event\r
-class e.g., for sending more complex data from one place to another. Apart\r
-from defining your event class, you will also need to define your own\r
-event table macro (which is quite long). Watch out to put in enough\r
-casts to the inherited event function. Here is an example:\r
+Under certain circumstances, you must define your own event class e.g., for\r
+sending more complex data from one place to another. Apart from defining your\r
+event class, you also need to define your own event table macro if you want to\r
+use event tables for handling events of this type.\r
 \r
-@code\r
-// code defining event\r
+Here is an example:\r
 \r
-class wxPlotEvent: public wxNotifyEvent\r
+@code\r
+// define a new event class\r
+class MyPlotEvent: public wxEvent\r
 {\r
 public:\r
-    wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );\r
+    MyPlotEvent(wxEventType eventType, int winid, const wxPoint& pos)\r
+        : wxEvent(winid, eventType),\r
+          m_pos(pos)\r
+    {\r
+    }\r
 \r
     // accessors\r
-    wxPlotCurve *GetCurve()\r
-        { return m_curve; }\r
+    wxPoint GetPoint() const { return m_pos; }\r
 \r
-    // required for sending with wxPostEvent()\r
-    virtual wxEvent *Clone() const;\r
+    // implement the base class pure virtual\r
+    virtual wxEvent *Clone() const { return new MyPlotEvent(*this); }\r
 \r
 private:\r
-    wxPlotCurve   *m_curve;\r
+    const wxPoint m_pos;\r
 };\r
 \r
-extern const wxEventType wxEVT_PLOT_ACTION;\r
-typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);\r
-\r
-#define wxPlotEventHandler(func) \\r
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxPlotEventFunction, &func)\r
-#define EVT_PLOT(id, fn) \\r
-    wx__DECLARE_EVT1(wxEVT_PLOT_ACTION, id, wxPlotEventHandler(fn))\r
+// we define a single MY_PLOT_CLICKED event type associated with the class\r
+// above but typically you are going to have more than one event type, e.g. you\r
+// could also have MY_PLOT_ZOOMED or MY_PLOT_PANNED &c -- in which case you\r
+// would just add more similar lines here\r
+wxDEFINE_EVENT(MY_PLOT_CLICKED, MyPlotEvent);\r
 \r
 \r
-// code implementing the event type and the event class\r
+// if you want to support old compilers you need to use some ugly macros:\r
+typedef void (wxEvtHandler::*MyPlotEventFunction)(MyPlotEvent&);\r
+#define MyPlotEventHandler(func) wxEVENT_HANDLER_CAST(MyPlotEventFunction, func)\r
 \r
-DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION )\r
+// if your code is only built sing reasonably modern compilers, you could just\r
+// do this instead:\r
+#define MyPlotEventHandler(func) (&func)\r
 \r
-wxPlotEvent::wxPlotEvent( ... )\r
-{\r
-    ...\r
-}\r
+// finally define a macro for creating the event table entries for the new\r
+// event type\r
+//\r
+// remember that you don't need this at all if you only use Connect() and that\r
+// you can replace MyPlotEventHandler(func) with just &func unless you use a\r
+// really old compiler\r
+#define MY_EVT_PLOT_CLICK(id, func) \\r
+    wx__DECLARE_EVT1(MY_PLOT_CLICKED, id, MyPlotEventHandler(func))\r
 \r
 \r
-// user code intercepting the event\r
-\r
+// example of code handling the event (you will use one of these methods, not\r
+// both, of course):\r
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)\r
-EVT_PLOT  (ID_MY_WINDOW, MyFrame::OnPlot)\r
+    EVT_PLOT(ID_MY_WINDOW, MyFrame::OnPlot)\r
 END_EVENT_TABLE()\r
 \r
-void MyFrame::OnPlot( wxPlotEvent &event )\r
+MyFrame::MyFrame()\r
 {\r
-    wxPlotCurve *curve = event.GetCurve();\r
+    Connect(ID_MY_WINDOW, MY_PLOT_CLICKED, &MyFrame::OnPlot);\r
 }\r
 \r
+void MyFrame::OnPlot(MyPlotEvent& event)\r
+{\r
+    ... do something with event.GetPoint() ...\r
+}\r
 \r
-// user code sending the event\r
 \r
+// example of code generating the event:\r
 void MyWindow::SendEvent()\r
 {\r
-    wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() );\r
-    event.SetEventObject( this );\r
-    event.SetCurve( m_curve );\r
-    GetEventHandler()->ProcessEvent( event );\r
+    MyPlotEvent event(MY_PLOT_CLICKED, GetId(), wxPoint(...));\r
+    event.SetEventObject(this);\r
+    ProcessWindowEvent(event);\r
 }\r
 @endcode\r
 \r
 \r
+\r
 @section overview_events_misc Miscellaneous Notes\r
 \r
 @subsection overview_events_virtual Event Handlers vs Virtual Methods\r
@@ -755,6 +737,31 @@ If you use wxNewId() consistently in your application, you can be sure that
 your identifiers don't conflict accidentally.\r
 \r
 \r
+@subsection overview_events_custom_generic Generic Event Table Macros\r
+\r
+@beginTable\r
+@row2col{EVT_CUSTOM(event\, id\, func),\r
+        Allows you to add a custom event table\r
+        entry by specifying the event identifier (such as wxEVT_SIZE),\r
+        the window identifier, and a member function to call.}\r
+@row2col{EVT_CUSTOM_RANGE(event\, id1\, id2\, func),\r
+        The same as EVT_CUSTOM, but responds to a range of window identifiers.}\r
+@row2col{EVT_COMMAND(id\, event\, func),\r
+        The same as EVT_CUSTOM, but expects a member function with a\r
+        wxCommandEvent argument.}\r
+@row2col{EVT_COMMAND_RANGE(id1\, id2\, event\, func),\r
+        The same as EVT_CUSTOM_RANGE, but\r
+        expects a member function with a wxCommandEvent argument.}\r
+@row2col{EVT_NOTIFY(event\, id\, func),\r
+        The same as EVT_CUSTOM, but\r
+        expects a member function with a wxNotifyEvent argument.}\r
+@row2col{EVT_NOTIFY_RANGE(event\, id1\, id2\, func),\r
+        The same as EVT_CUSTOM_RANGE, but\r
+        expects a member function with a wxNotifyEvent argument.}\r
+@endTable\r
+\r
+\r
+\r
 @subsection overview_events_macros Event Handling Summary\r
 \r
 For the full list of event classes, please see the\r
index 6cc36544063037bcb982718ff62a6f8b0aa9f333..030d3415f623f558974cea1a97ff9c4efa6dd779 100644 (file)
@@ -3497,14 +3497,125 @@ wxEventType wxEVT_NULL;
 
 /**
     Initializes a new event type using wxNewEventType().
+
+    @deprecated Use wxDEFINE_EVENT() instead
 */
 #define DEFINE_EVENT_TYPE(name)     const wxEventType name = wxNewEventType();
 
 /**
     Generates a new unique event type.
+
+    Usually this function is only used by wxDEFINE_EVENT() and not called
+    directly.
 */
 wxEventType wxNewEventType();
 
+/**
+    Define a new event type associated with the specified event class.
+
+    This macro defines a new unique event type @a name associated with the
+    event class @a cls.
+
+    For example:
+    @code
+    wxDEFINE_EVENT(MY_COMMAND_EVENT, wxCommandEvent);
+
+    class MyCustomEvent : public wxEvent { ... };
+    wxDEFINE_EVENT(MY_CUSTOM_EVENT, MyCustomEvent);
+    @endcode
+
+    @see wxDECLARE_EVENT(), @ref overview_events_custom
+ */
+#define wxDEFINE_EVENT(name, cls) \
+    const wxEventTypeTag< cls > name(wxNewEventType())
+
+/**
+    Declares a custom event type.
+
+    This macro declares a variable called @a name which must be defined
+    elsewhere using wxDEFINE_EVENT().
+
+    The class @a cls must be the wxEvent-derived class associated with the
+    events of this type and its full declaration must be visible from the point
+    of use of this macro.
+ */
+#define wxDECLARE_EVENT(name, cls) \
+        wxDECLARE_EXPORTED_EVENT(wxEMPTY_PARAMETER_VALUE, name, cls)
+
+/**
+    Variant of wxDECLARE_EVENT() used for event types defined inside a shared
+    library.
+
+    This is mostly used by wxWidgets internally, e.g.
+    @code
+    wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEvent)
+    @endcode
+ */
+#define wxDECLARE_EXPORTED_EVENT( expdecl, name, cls ) \
+    extern const expdecl wxEventTypeTag< cls > name;
+
+/**
+    Helper macro for definition of custom event table macros.
+
+    This macro must only be used if wxEVENTS_COMPATIBILITY_2_8 is 1, otherwise
+    it is better and more clear to just use the address of the function
+    directly as this is all this macro does in this case. However it needs to
+    explicitly cast @a func to @a functype, which is the type of wxEvtHandler
+    member function taking the custom event argument when
+    wxEVENTS_COMPATIBILITY_2_8 is 0.
+
+    See wx__DECLARE_EVT0 for an example of use.
+
+    @see @ref overview_events_custom_ownclass
+ */
+#define wxEVENT_HANDLER_CAST(functype, func) (&func)
+
+//@{
+/**
+    These macros are used to define event table macros for handling custom
+    events.
+
+    Example of use:
+    @code
+    class MyEvent : public wxEvent { ... };
+
+    // note that this is not necessary unless using old compilers: for the
+    // reasonably new ones just use &func instead of MyEventHandler(func)
+    typedef void (wxEvtHandler::*MyEventFunction)(MyEvent&);
+    #define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func)
+
+    wxDEFINE_EVENT(MY_EVENT_TYPE, MyEvent);
+
+    #define EVT_MY(id, func) \
+        wx__DECLARE_EVT1(MY_EVENT_TYPE, id, MyEventHandler(func))
+
+    ...
+
+    BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+        EVT_MY(wxID_ANY, MyFrame::OnMyEvent)
+    END_EVENT_TABLE()
+    @endcode
+
+    @param evt
+        The event type to handle.
+    @param id
+        The identifier of events to handle.
+    @param id1
+        The first identifier of the range.
+    @param id2
+        The second identifier of the range.
+    @param fn
+        The event handler method.
+ */
+#define wx__DECLARE_EVT2(evt, id1, id2, fn) \
+    DECLARE_EVENT_TABLE_ENTRY(evt, id1, id2, fn, NULL),
+#define wx__DECLARE_EVT1(evt, id, fn) \
+    wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)
+#define wx__DECLARE_EVT0(evt, fn) \
+    wx__DECLARE_EVT1(evt, wxID_ANY, fn)
+//@}
+
+
 /**
     Use this macro inside a class declaration to declare a @e static event table
     for that class.