Defining Custom Events

team bbl


If you want to define your own event class and macros, you need to follow these steps:

1.

Derive your class from a suitable class, declaring dynamic type information and including a Clone function. You may or may not want to add data members and accessors. Derive from wxCommandEvent if you want the event to propagate up the window hierarchy, and from wxNotifyEvent if you also want handlers to be able to call Veto.

2.

Define a typedef for the event handler function.

3.

Define a table of event types for the individual events your event class supports. The event table is defined in your header with BEGIN_DECLARE_EVENT_TYPES()... END_DECLARE_EVENT_TYPES() and each type is declared with DECLARE_EVENT_TABLE(name, integer). Then in your implementation file, write DEFINE_EVENT_TYPE(name).

4.

Define an event table macro for each event type.

Let's make this clearer with an example. Say we want to implement a new control class, wxFontSelectorCtrl, which displays a font preview; the user can click on the preview to pop up a font selector dialog to change the font. The application may want to intercept the font selection event, so we'll send a custom command event from within our low-level mouse handling code.

We will need to define a new event class wxFontSelectorCtrlEvent. An application will be able to route font change events to an event handler with the macro EVT_FONT_SELECTION_CHANGED(id, func), which uses the single event type wxEVT_COMMAND_FONT_SELECTION_CHANGED. Here's what we need in our new control header file, as well as the control declaration itself (not shown):

[View full width]

/*! * Font selector event class */ class wxFontSelectorCtrlEvent : public wxNotifyEvent { public: wxFontSelectorCtrlEvent(wxEventType commandType = wxEVT_NULL, int id = 0): wxNotifyEvent(commandType, id) {} wxFontSelectorCtrlEvent(const wxFontSelectorCtrlEvent& event): wxNotifyEvent(event) {} virtual wxEvent *Clone() const { return new wxFontSelectorCtrlEvent(*this); } DECLARE_DYNAMIC_CLASS(wxFontSelectorCtrlEvent); }; typedef void (wxEvtHandler::*wxFontSelectorCtrlEventFunction) (wxFontSelectorCtrlEvent&); /*! * Font selector control events and macros for handling them */ BEGIN_DECLARE_EVENT_TYPES() DECLARE_EVENT_TYPE(wxEVT_COMMAND_FONT_SELECTION_CHANGED, 801) END_DECLARE_EVENT_TYPES() #define EVT_FONT_SELECTION_CHANGED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_FONT_SELECTION_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxFontSelectorCtrlEventFunction) & fn, (wxObject *) NULL ),

In our implementation file, we write

 DEFINE_EVENT_TYPE(wxEVT_COMMAND_FONT_SELECTION_CHANGED) IMPLEMENT_DYNAMIC_CLASS(wxFontSelectorCtrlEvent, wxNotifyEvent) 

To send the custom event, the font selector control can call ProcessEvent when a selection is detected from within the mouse handling code:

 wxFontSelectorCtrlEvent event(                     wxEVT_COMMAND_FONT_SELECTION_CHANGED, GetId()); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); 

Now an application can write a font selection event handler, for example:

 BEGIN_EVENT_TABLE(MyDialog, wxDialog)   EVT_FONT_SELECTION_CHANGED(ID_FONTSEL, MyDialog::OnChangeFont) END_EVENT_TABLE() void MyDialog::OnChangeFont(wxFontSelectorCtrlEvent& event) {     // Take appropriate action when the font selection changed     ... } 

The event identifier value (801) is not used in recent versions of wxWidgets and is only included for compatibility with wxWidgets 2.4.

Let's take another look at the event macro definition:

[View full width]

#define EVT_FONT_SELECTION_CHANGED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_FONT_SELECTION_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxFontSelectorCtrlEventFunction) & fn, (wxObject *) NULL ),

The macro places information into an array that forms the event table, which is why the syntax looks rather strange. The five entries in the event table record are as follows:

  1. The event type. One event class can handle several types, but in our example, we only define one event type, and therefore there is only one event table macro. This type must match the type of the event being processed for the event handler to be called.

  2. The identifier value passed to the macro. The event handler function will only be called if the value in the table matches the value in the event being processed.

  3. A second identifier value, used when specifying a range of values. -1 indicates that there is no second value.

  4. The event handler function. The sequence of casts is needed for some compilers, and this is where the member function typedef is used.

  5. User data, normally NULL.

The full custom event example can be found in examples/chap03, and it includes a font selection control implementation and handy validator class that you can use in your own applications. You can also look at include/wx/event.h in your wxWidgets distribution for more inspiration.

    team bbl



    Cross-Platform GUI Programming with wxWidgets
    Cross-Platform GUI Programming with wxWidgets
    ISBN: 0131473816
    EAN: 2147483647
    Year: 2005
    Pages: 262

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net