Events

From WxWiki

Jump to: navigation, search

In addition to the material below see the event project in the samples directory and the Event Handling Overview.

Contents

[edit] Introduction

An event is something that occurs inside or outside the application. An event might be initiated by the user, another application or the operating system. A mechanism is needed to react to the events pertinent to the application. An event table such as the one below tells wxWidgets how to map events to member functions. An event table is defined in the implementation file (.cpp).

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
   EVT_MENU(wxID_EXIT, MyFrame::OnExit)
   EVT_SIZE(MyFrame::OnSize)
   EVT_BUTTON(BUTTON1, MyFrame::OnButton1)
END_EVENT_TABLE()

The above event table tells wxWidgets, when it receives a WM_SIZE event for MyFrame, to call the OnSize member function. The BEGIN_EVENT_TABLE macro declares that MyFrame, which is derived from wxFrame, owns this event table.

The member function that handles an event does not have to be virtual. In fact, the event handler ignores the virtual declaration. These functions have a similar form: the return type is void and they receive an event parameter. The type of this parameter depends on the event. For size events, wxSizeEvent is used. For menu commands and most control commands (e.g. a button), wxCommandEvent is used. When controls get more complicated, they use their own event class.

You must place a DECLARE_EVENT_TABLE macro in the class definition. For an example see The Full Implementation Of The TextFrame Class.

Note that the second argument of macro's like EVT_BUTTON must always be a member of the class specified in the first argument of BEGIN_EVENT_TABLE.

[edit] Identifier Sizes

It is worth noting that (at least on MS Windows) identifiers are 16 bits in size. If you declare your menu identifiers larger than 16 bits, everything will compile fine, but none of your events will work.

[edit] wxMenuBar Events

A wxMenuBar doesn't send events to itself, but to its parent frame. This might seem inconsistent, but it's actually convenient in all common situations.

Every event is associated with a wxEvent. Therefore, make sure you ALWAYS define a wxEvent to the function! The following example will crash in Release build (at least on MSW & with wxWidgets 2.4.2):

void MyFrame::OnExit( void )
{
// Do Something
}

This slightly changed example, however, will run just fine:

void MyFrame::OnExit( wxEvent& WXUNUSED(event) )
{
// Do Something
}

[edit] Event.Skip and Event.Veto

Taken from a post by Robin Dunn:

>>If the event is derived from a wxCommandEvent and you call
>>event.Skip(TRUE) the event continues up the chain to the top level
>>window. Otherwise the program returns to the function that posted the
>>event.
>
>
> That's exactly what I meant, if do nothing in the handler /and/ I do
> *not* call Skip(), then isn't the final result/effect the same as
> vetoing?

No, there is a big conceptual difference. Some events are so your code can *do* 
something in response to the event. For example, to repaint the window, to layout 
components when the size changes, to do something when an item is activated, etc.
Other events are there simply to *notify* your code that something is about to 
happen and are giving your code a chance to stop it from happening. Under normal 
circumstances you don't need to *do* anything for those events.

The Skip is different. It controls whether the parent class and/or the parent window will also have it's event table seached for a handler to be invoked for the event, and eventually (for many event types) whether the default platform level functionality will be invoked or not. Yes, in many cases catching an event and doing nothing will effectivly prevent some functionality from being executed, but it is in the cases where you are expected to *do* something when you catch the event and you don't do it. The notification events are at a high level and are just saying, "Oh, by the way I am about to do such-and-such, is that okay?"

I've never seen it done, but Skip and Veto could be combined. You could catch a notification event, Veto it, then call Skip giving the parent classes or windows a chance to unVeto it.

(It appears in wxWidgets 2.6.1 that calling Skip() after Veto() on an event causes the Veto() to be ignored.)

[edit] Inheriting Event Tables (Events in Derived Classes)

Say you made a new class derived from wxWizard, called MyWizardBase and it had an event table. Then you made a derived class of MyWizardBase called MyInstallWizard, and you wanted it to inherit the event table of MyWizardBase also, and perhaps add a few of its own.

To do so, you need the BEGIN_EVENT_TABLE( a, b ) macro, where b is the direct parent of the class a. So for this example it would be BEGIN_EVENT_TABLE( MyInstallWizard, MyWizardBase ).

If you instead wrote BEGIN_EVENT_TABLE( MyInstallWizard, wxWizard ), things would still compile perfectly, but you would be wondering why none of the MyWizardBase events seemed to be working.

[edit] Unique ID

If you don't want to specify a unique ID in an EVT_-macro, you can use wxID_ANY (-1).

[edit] Using Connect()

Connect() is more flexible - it does the same thing as EVT_, but at run-time instead of compile-time. Don't mess with ProcessEvent(). See the Example Of Using Connect For Events.

This is particularly useful in situations where you would normally have to derive from a wxWidgets class for the sole purpose of adding some event handlers.

However, the above example of Connect() doesn't cover that situation; it shows how to add dynamic events to a child class (MyFrame) that you create. In wxWidgets 2.6.3, pass an external class's method in the eventSink parameter. In wxWidgets 2.4.2, kludge around it Using Connect To Add Events To An Existing Class.

[edit] Documentation

wxEVT_ macros are usually listed under wxEvent Derivatives

[edit] Custom Events

You can create Custom Events.

[edit] Short Summary of Events

A list of available events (generated from the XML class information) is available at http://www.bzzt.net/~wxwidgets/xmldocs/applications/eventslist/eventslist.html

[edit] Preprocessor Commands in the Event Table

Just a bit of a warning: It appears that you cannot use preprocessor commands inside the Event Table. It will not cause any compiler errors or warnings.

(4/5/04) win32 2.4.2 with #ifdef

  • I've had no problems with this on MSW from about 2.5.1 through 2.6.3 with MSVC++. Were event tables defined significantly different with 2.4.2? --Tierra 08:58, 16 May 2006 (PDT)
Personal tools