git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58144
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
void Skip(bool skip = true) { m_skipped = skip; }
bool GetSkipped() const { return m_skipped; }
void Skip(bool skip = true) { m_skipped = skip; }
bool GetSkipped() const { return m_skipped; }
- // this function is used to create a copy of the event polymorphically and
+ // This function is used to create a copy of the event polymorphically and
// all derived classes must implement it because otherwise wxPostEvent()
// for them wouldn't work (it needs to do a copy of the event)
virtual wxEvent *Clone() const = 0;
// all derived classes must implement it because otherwise wxPostEvent()
// for them wouldn't work (it needs to do a copy of the event)
virtual wxEvent *Clone() const = 0;
m_propagationLevel = propagationLevel;
}
m_propagationLevel = propagationLevel;
}
+
+ // This is for internal use only and is only called by
+ // wxEvtHandler::ProcessEvent() to check whether it's the first time this
+ // event is being processed
+ bool WasProcessed()
+ {
+ if ( m_wasProcessed )
+ return true;
+
+ m_wasProcessed = true;
+
+ return false;
+ }
+
protected:
wxObject* m_eventObject;
wxEventType m_eventType;
protected:
wxObject* m_eventObject;
wxEventType m_eventType;
bool m_skipped;
bool m_isCommandEvent;
bool m_skipped;
bool m_isCommandEvent;
+ // initially false but becomes true as soon as WasProcessed() is called for
+ // the first time, as this is done only by ProcessEvent() it explains the
+ // variable name: it becomes true after ProcessEvent() was called at least
+ // once for this event
+ bool m_wasProcessed;
+
protected:
wxEvent(const wxEvent&); // for implementing Clone()
wxEvent& operator=(const wxEvent&); // for derived classes operator=()
protected:
wxEvent(const wxEvent&); // for implementing Clone()
wxEvent& operator=(const wxEvent&); // for derived classes operator=()
void OnSinkDestroyed( wxEvtHandler *sink );
void OnSinkDestroyed( wxEvtHandler *sink );
- // The method processing the event in this event handler (or rather in this
- // event handler chain as it also tries the next handler and so on), i.e.
- // it returns true if we processed this event or false if we didn't but
- // does not call TryParent() in the latter case. It also doesn't call
- // wxApp::FilterEvent() before processing it, this is supposed to be done
- // by the public ProcessEvent() only once for every event we handle.
+ // The method tries to process the event in this event handler.
//
// It is meant to be called from ProcessEvent() only and is not virtual,
// additional event handlers can be hooked into the normal event processing
//
// It is meant to be called from ProcessEvent() only and is not virtual,
// additional event handlers can be hooked into the normal event processing
m_callbackUserData = NULL;
m_isCommandEvent = false;
m_propagationLevel = wxEVENT_PROPAGATE_NONE;
m_callbackUserData = NULL;
m_isCommandEvent = false;
m_propagationLevel = wxEVENT_PROPAGATE_NONE;
+ m_wasProcessed = false;
}
wxEvent::wxEvent(const wxEvent& src)
}
wxEvent::wxEvent(const wxEvent& src)
, m_propagationLevel(src.m_propagationLevel)
, m_skipped(src.m_skipped)
, m_isCommandEvent(src.m_isCommandEvent)
, m_propagationLevel(src.m_propagationLevel)
, m_skipped(src.m_skipped)
, m_isCommandEvent(src.m_isCommandEvent)
+ , m_wasProcessed(false)
m_skipped = src.m_skipped;
m_isCommandEvent = src.m_isCommandEvent;
m_skipped = src.m_skipped;
m_isCommandEvent = src.m_isCommandEvent;
+ // don't change m_wasProcessed
+
bool wxEvtHandler::ProcessEvent(wxEvent& event)
{
// allow the application to hook into event processing
bool wxEvtHandler::ProcessEvent(wxEvent& event)
{
// allow the application to hook into event processing
+ //
+ // note that we should only do it if we're the first event handler called
+ // to avoid calling FilterEvent() multiple times as the event goes through
+ // the event handler chain and possibly upwards the window hierarchy
+ if ( !event.WasProcessed() )
- int rc = wxTheApp->FilterEvent(event);
- if ( rc != -1 )
- wxASSERT_MSG( rc == 1 || rc == 0,
- _T("unexpected wxApp::FilterEvent return value") );
+ int rc = wxTheApp->FilterEvent(event);
+ if ( rc != -1 )
+ {
+ wxASSERT_MSG( rc == 1 || rc == 0,
+ "unexpected wxApp::FilterEvent return value" );
+ return rc != 0;
+ }
+ //else: proceed normally
- //else: proceed normally
}
if ( ProcessEventHere(event) )
return true;
}
if ( ProcessEventHere(event) )
return true;
+ // pass the event to the next handler, notice that we shouldn't call
+ // TryParent() even if it doesn't handle the event as the last handler in
+ // the chain will do it
+ if ( GetNextHandler() )
+ return GetNextHandler()->ProcessEvent(event);
+
// propagate the event upwards the window chain and/or to the application
// object if it wasn't processed at this level
return TryParent(event);
// propagate the event upwards the window chain and/or to the application
// object if it wasn't processed at this level
return TryParent(event);
bool wxEvtHandler::ProcessEventHere(wxEvent& event)
{
bool wxEvtHandler::ProcessEventHere(wxEvent& event)
{
- // An event handler can be enabled or disabled
- if ( GetEvtHandlerEnabled() )
- {
- // if we have a validator, it has higher priority than our own event
- // table
- if ( TryValidator(event) )
- return true;
+ // 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;
+ // If we have a validator, it has higher priority than our own event
+ // handlers
+ if ( TryValidator(event) )
+ return true;
- // Then static per-class event tables
- if ( GetEventHashTable().HandleEvent(event, this) )
- return true;
- }
+ // Handle per-instance dynamic event tables first
+ if ( m_dynamicEvents && SearchDynamicEventTable(event) )
+ return true;
- // Try going down the event handler chain
- if ( GetNextHandler() && GetNextHandler()->ProcessEventHere(event) )
+ // Then static per-class event tables
+ if ( GetEventHashTable().HandleEvent(event, this) )
return true;
// We don't have a handler for this event.
return true;
// We don't have a handler for this event.