Custom event summary

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 from wxEvent 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
DECLARE_EVENT_TYPE(name, value)

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

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(id, event, func) The same as EVT_CUSTOM, but expects a member function with a wxNotifyEvent argument.
EVT_NOTIFY_RANGE(id1, id2, event, 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_MACRO( 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 );
}

ymasuda 平成17年11月19日