\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
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
/**
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.