+ wxASSERT_MSG( rc == 1 || rc == 0,
+ "unexpected wxApp::FilterEvent return value" );
+
+ return rc != 0;
+ }
+ //else: proceed normally
+ }
+ }
+
+ // Short circuit the event processing logic if we're requested to process
+ // this event in this handler only, see DoTryChain() for more details.
+ if ( event.ShouldProcessOnlyIn(this) )
+ return TryBeforeAndHere(event);
+
+
+ // Try to process the event in this handler itself.
+ if ( ProcessEventLocally(event) )
+ {
+ // It is possible that DoTryChain() called from ProcessEventLocally()
+ // returned true but the event was not really processed: this happens
+ // if a custom handler ignores the request to process the event in this
+ // handler only and in this case we should skip the post processing
+ // done in TryAfter() but still return the correct value ourselves to
+ // indicate whether we did or did not find a handler for this event.
+ return !event.GetSkipped();
+ }
+
+ // If we still didn't find a handler, propagate the event upwards the
+ // window chain and/or to the application object.
+ if ( TryAfter(event) )
+ return true;
+
+
+ // No handler found anywhere, bail out.
+ return false;
+}
+
+bool wxEvtHandler::ProcessEventLocally(wxEvent& event)
+{
+ // Try the hooks which should be called before our own handlers and this
+ // handler itself first. Notice that we should not call ProcessEvent() on
+ // this one as we're already called from it, which explains why we do it
+ // here and not in DoTryChain()
+ return TryBeforeAndHere(event) || DoTryChain(event);
+}
+
+bool wxEvtHandler::DoTryChain(wxEvent& event)
+{
+ for ( wxEvtHandler *h = GetNextHandler(); h; h = h->GetNextHandler() )
+ {
+ // We need to process this event at the level of this handler only
+ // right now, the pre-/post-processing was either already done by
+ // ProcessEvent() from which we were called or will be done by it when
+ // we return.
+ //
+ // However we must call ProcessEvent() and not TryHereOnly() because the
+ // existing code (including some in wxWidgets itself) expects the
+ // overridden ProcessEvent() in its custom event handlers pushed on a
+ // window to be called.
+ //
+ // So we must call ProcessEvent() but it must not do what it usually
+ // does. To resolve this paradox we set up a special flag inside the
+ // object itself to let ProcessEvent() know that it shouldn't do any
+ // pre/post-processing for this event if it gets it. Note that this
+ // only applies to this handler, if the event is passed to another one
+ // by explicitly calling its ProcessEvent(), pre/post-processing should
+ // be done as usual.
+ //
+ // Final complication is that if the implementation of ProcessEvent()
+ // called wxEvent::DidntHonourProcessOnlyIn() (as the gross hack that
+ // is wxScrollHelperEvtHandler::ProcessEvent() does) and ignored our
+ // request to process event in this handler only, we have to compensate
+ // for it by not processing the event further because this was already
+ // done by that rogue event handler.
+ wxEventProcessInHandlerOnly processInHandlerOnly(event, h);
+ if ( h->ProcessEvent(event) )
+ {
+ // Make sure "skipped" flag is not set as the event was really
+ // processed in this case. Normally it shouldn't be set anyhow but
+ // make sure just in case the user code does something strange.
+ event.Skip(false);
+
+ return true;
+ }
+
+ if ( !event.ShouldProcessOnlyIn(h) )
+ {
+ // Still return true to indicate that no further processing should
+ // be undertaken but ensure that "skipped" flag is set so that the
+ // caller knows that the event was not really processed.
+ event.Skip();
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool wxEvtHandler::TryHereOnly(wxEvent& event)
+{
+ // If the event handler is disabled it doesn't process any events
+ if ( !GetEvtHandlerEnabled() )
+ return false;
+
+ // Handle per-instance dynamic event tables first
+ if ( m_dynamicEvents && SearchDynamicEventTable(event) )
+ return true;