-The normal order of event table searching by ProcessEvent is as follows:
-
-@li If the object is disabled (via a call to wxEvtHandler::SetEvtHandlerEnabled)
- the function skips to step (6).
-@li If the object is a wxWindow, @b ProcessEvent is recursively called on the window's
- wxValidator. If this returns @true, the function exits.
-@li @b SearchEventTable is called for this event handler. If this fails, the base
- class table is tried, and so on until no more tables exist or an appropriate
- function was found, in which case the function exits.
-@li The search is applied down the entire chain of event handlers (usually the chain has
- a length of one). If this succeeds, the function exits.
-@li If the object is a wxWindow and the event is set to set to propagate (in the library only
- wxCommandEvent based events are set to propagate), @b ProcessEvent is recursively applied
- to the parent window's event handler. If this returns @true, the function exits.
-@li Finally, @b ProcessEvent is called on the wxApp object.
-
-<b>Pay close attention to Step 5</b>. People often overlook or get
-confused by this powerful feature of the wxWidgets event processing
-system. To put it a different way, events set to propagate
-(see wxEvent::ShouldPropagate)
-(most likely derived either directly or indirectly from wxCommandEvent)
-will travel up the containment hierarchy from child to parent until the
-maximal propagation level is reached or an event handler is found that
-doesn't call @c event.Skip().
+A common example of a functor is boost::function<>:
+
+@code
+using namespace boost;
+
+void MyHandler::OnExit( wxCommandEvent & )
+{
+ // Do something useful
+}
+
+MyHandler myHandler;
+
+MyFrame::MyFrame()
+{
+ function< void ( wxCommandEvent & ) > exitHandler( bind( &MyHandler::OnExit, &myHandler, _1 ));
+
+ Bind( wxEVT_COMMAND_MENU_SELECTED, exitHandler, wxID_EXIT );
+}
+@endcode
+
+
+With the aid of boost::bind<>() you can even use methods or functions which
+don't quite have the correct signature:
+
+@code
+void MyHandler::OnExit( int exitCode, wxCommandEvent &, wxString goodByeMessage )
+{
+ // Do something useful
+}
+
+MyHandler myHandler;
+
+MyFrame::MyFrame()
+{
+ function< void ( wxCommandEvent & ) > exitHandler(
+ bind( &MyHandler::OnExit, &myHandler, EXIT_FAILURE, _1, "Bye" ));
+
+ Bind( wxEVT_COMMAND_MENU_SELECTED, exitHandler, wxID_EXIT );
+}
+@endcode
+
+
+To summarize, using Bind<>() requires slightly more typing but is much more
+flexible than using static event tables so don't hesitate to use it when you
+need this extra power. On the other hand, event tables are still perfectly fine
+in simple situations where this extra flexibility is not needed.
+
+
+@section overview_events_processing How Events are Processed
+
+The previous sections explain how to define event handlers but don't address
+the question of how exactly wxWidgets finds the handler to call for the
+given event. This section describes the algorithm used in detail.
+
+When an event is received from the windowing system, wxWidgets calls
+wxEvtHandler::ProcessEvent() on the first event handler object belonging to the
+window generating the event. The normal order of event table searching by
+ProcessEvent() is as follows, with the event processing stopping as soon as a
+handler is found (unless the handler calls wxEvent::Skip() in which case it
+doesn't count as having handled the event and the search continues):
+<ol>
+ <li value="0">
+ Before anything else happens, wxApp::FilterEvent() is called. If it returns
+ anything but -1 (default), the event handling stops immediately.
+ </li>
+
+ <li value="1">
+ If this event handler is disabled via a call to
+ wxEvtHandler::SetEvtHandlerEnabled() the next three steps are skipped and
+ the event handler resumes at step (5).
+ </li>
+
+ <li value="2">
+ If the object is a wxWindow and has an associated validator, wxValidator
+ gets a chance to process the event.
+ </li>
+
+ <li value="3">
+ The list of dynamically bind event handlers, i.e., those for which
+ Bind<>() was called, is consulted. Notice that this is done before
+ checking the static event table entries, so if both a dynamic and a static
+ event handler match the same event, the static one is never going to be
+ used.
+ </li>
+
+ <li value="4">
+ The event table containing all the handlers defined using the event table
+ macros in this class and its base classes is examined. Notice that this
+ means that any event handler defined in a base class will be executed at
+ this step.
+ </li>
+
+ <li value="5">
+ The event is passed to the next event handler, if any, in the event handler
+ chain, i.e., the steps (1) to (4) are done for it. This chain can be formed
+ using wxEvtHandler::SetNextHandler():
+ @image html overview_events_chain.png
+ (referring to the image, if @c A->ProcessEvent is called and it doesn't handle
+ the event, @c B->ProcessEvent will be called and so on...).
+ In the case of wxWindow you can build a stack (implemented using wxEvtHandler
+ double-linked list) using wxWindow::PushEventHandler():
+ @image html overview_events_winstack.png
+ (referring to the image, if @c W->ProcessEvent is called, it immediately calls
+ @c A->ProcessEvent; if nor @c A nor @c B handle the event, then the wxWindow
+ itself is used - i.e. the dynamically bind event handlers and static
+ event table entries of wxWindow are looked as the last possibility, after
+ all pushed event handlers were tested).
+ Note however that usually there are no wxEvtHandler chains nor wxWindows stacks
+ so this step will usually do anything.
+ </li>
+
+ <li value="6">
+ If the object is a wxWindow and the event is set to propagate (by default
+ only wxCommandEvent-derived events are set to propagate), then the
+ processing restarts from the step (1) (and excluding the step (7)) for the
+ parent window. If this object is not a window but the next handler exists,
+ the event is passed to its parent if it is a window. This ensures that in a
+ common case of (possibly several) non-window event handlers pushed on top
+ of a window, the event eventually reaches the window parent.
+ </li>
+
+ <li value="7">
+ Finally, i.e., if the event is still not processed, the wxApp object itself
+ (which derives from wxEvtHandler) gets a last chance to process it.
+ </li>
+</ol>
+
+<em>Please pay close attention to step 6!</em> People often overlook or get
+confused by this powerful feature of the wxWidgets event processing system. The
+details of event propagation up the window hierarchy are described in the
+next section.
+
+Also please notice that there are additional steps in the event handling for
+the windows-making part of wxWidgets document-view framework, i.e.,
+wxDocParentFrame, wxDocChildFrame and their MDI equivalents wxDocMDIParentFrame
+and wxDocMDIChildFrame. The parent frame classes modify step (2) above to
+send the events received by them to wxDocManager object first. This object, in
+turn, sends the event to the current view and the view itself lets its
+associated document process the event first. The child frame classes send
+the event directly to the associated view which still forwards it to its
+document object. Notice that to avoid remembering the exact order in which the
+events are processed in the document-view frame, the simplest, and recommended,
+solution is to only handle the events at the view classes level, and not in the
+document or document manager classes
+
+
+@subsection overview_events_propagation How Events Propagate Upwards
+
+As mentioned above, the events of the classes deriving from wxCommandEvent are
+propagated by default to the parent window if they are not processed in this
+window itself. But although by default only the command events are propagated
+like this, other events can be propagated as well because the event handling
+code uses wxEvent::ShouldPropagate() to check whether an event should be
+propagated. It is also possible to propagate the event only a limited number of
+times and not until it is processed (or a top level parent window is reached).