General approach
Since version 2.2.x of wxWidgets, each event type is identified by ID which is given to the event type at runtime which makes it possible to add new event types to the library or application without risking ID clashes (two different event types mistakingly getting the same event ID). This event type ID is stored in a struct of type const wxEventType.
In order to define a new event type, there are principally two choices. One is to define a entirely new event class (typically deriving fromwxEvent
or wxCommandEvent. The other is to use the existing event classes and give them an new event type. You'll have to define and declare a new event type using either way, and this is done using the following macros:
// in the header of the source file
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(name, value)
END_DECLARE_EVENT_TYPES()
// in the implementation
DEFINE_EVENT_TYPE(name)
You can ignore the value parameter of the DECLARE_EVENT_TYPE macro since it used only for backwards compatibility with wxWidgets 2.0.x based applications where you have to give the event type ID an explicit value.
See also the event sample for an example of code defining and working with the custom event types.
Using existing event classes
If you just want to use a wxCommandEvent with a new event type, you can then use one of the generic event table macros listed below, without having to define a new macro yourself. This also has the advantage that you won't have to define a new wxEvent::Clone()method for posting events between threads etc. This could look like this in your code:
DECLARE_EVENT_TYPE(wxEVT_MY_EVENT, -1)
DEFINE_EVENT_TYPE(wxEVT_MY_EVENT)
// user code intercepting the event
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU (wxID_EXIT, MyFrame::OnExit)
// ....
EVT_COMMAND (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent)
END_EVENT_TABLE()
void MyFrame::OnMyEvent( wxCommandEvent &event )
{
// do something
wxString text = event.GetText();
}
// user code sending the event
void MyWindow::SendEvent()
{
wxCommandEvent event( wxEVT_MY_EVENT, GetId() );
event.SetEventObject( this );
// Give it some contents
event.SetText( wxT("Hallo") );
// Send it
GetEventHandler()->ProcessEvent( event );
}
Generic event table macros
EVT_CUSTOM(event, id, func) Allows you to add a custom event table entry by specifying the event identifier (such as wxEVT_SIZE), the window identifier, and a member function to call.
EVT_CUSTOM_RANGE(event, id1, id2, func) The same as EVT_CUSTOM, but responds to a range of window identifiers.
EVT_COMMAND(id, event, func) The same as EVT_CUSTOM, but expects a member function with a wxCommandEvent argument.
EVT_COMMAND_RANGE(id1, id2, event, func) The same as EVT_CUSTOM_RANGE, but expects a member function with a wxCommandEvent argument.
EVT_NOTIFY(event, id, func) The same as EVT_CUSTOM, but expects a member function with a wxNotifyEvent argument.
EVT_NOTIFY_RANGE(event, id1, id2, func) The same as EVT_CUSTOM_RANGE, but expects a member function with a wxNotifyEvent argument.
Defining your own event class
Under certain circumstances, it will be required to define your own event class e.g. for sending more complex data from one place to another. Apart from defining your event class, you will also need to define your own event table macro (which is quite long). Watch out to put in enough casts to the inherited event function. Here is an example, taken mostly from the wxPlot library, which is in the contrib section of the wxWidgets sources.
// code defining event
class wxPlotEvent: public wxNotifyEvent
{
public:
wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );
// accessors
wxPlotCurve *GetCurve()
{ return m_curve; }
// required for sending with wxPostEvent()
wxEvent* Clone();
private:
wxPlotCurve *m_curve;
};
DECLARE_EVENT_TYPE( wxEVT_PLOT_ACTION, -1 )
typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);
#define EVT_PLOT(id, fn) /
DECLARE_EVENT_TABLE_ENTRY( wxEVT_PLOT_ACTION, id, -1, /
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) /
wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ),
// code implementing the event type and the event class
DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION )
wxPlotEvent::wxPlotEvent( ...
// user code intercepting the event
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_PLOT (ID_MY_WINDOW, MyFrame::OnPlot)
END_EVENT_TABLE()
void MyFrame::OnPlot( wxPlotEvent &event )
{
wxPlotCurve *curve = event.GetCurve();
}
// user code sending the event
void MyWindow::SendEvent()
{
wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() );
event.SetEventObject( this );
event.SetCurve( m_curve );
GetEventHandler()->ProcessEvent( event );
}