m_callbackUserData = NULL;
m_isCommandEvent = false;
m_propagationLevel = wxEVENT_PROPAGATE_NONE;
+ m_wasProcessed = false;
}
wxEvent::wxEvent(const wxEvent& src)
, 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;
+ // don't change m_wasProcessed
+
return *this;
}
const size_t count = eventEntryTable.GetCount();
for (size_t n = 0; n < count; n++)
{
- if ( wxEvtHandler::
- ProcessEventIfMatches(*eventEntryTable[n], self, event) )
- {
+ const wxEventTableEntry& entry = *eventEntryTable[n];
+ if ( wxEvtHandler::ProcessEventIfMatchesId(entry, self, event) )
return true;
- }
}
}
* Event table stuff
*/
/* static */ bool
-wxEvtHandler::ProcessEventIfMatches(const wxEventTableEntryBase& entry,
- wxEvtHandler *handler,
- wxEvent& event)
+wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase& entry,
+ wxEvtHandler *handler,
+ wxEvent& event)
{
int tableId1 = entry.m_id,
tableId2 = entry.m_lastId;
bool wxEvtHandler::ProcessEvent(wxEvent& event)
{
// allow the application to hook into event processing
- if ( wxTheApp )
+ //
+ // 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 )
+ if ( wxTheApp )
{
- 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;
+ return rc != 0;
+ }
+ //else: proceed normally
}
- //else: proceed normally
}
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);
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.
const wxEventTableEntry& entry = table.entries[i];
if ( eventType == entry.m_eventType )
{
- if ( ProcessEventIfMatches(entry, this, event) )
+ if ( ProcessEventIfMatchesId(entry, this, event) )
return true;
}
}
if ((entry->m_id == id) &&
((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
- (*entry->m_fn == func) &&
+ entry->m_fn->Matches(func) &&
((entry->m_callbackUserData == userData) || !userData))
{
delete entry->m_callbackUserData;
// call Disconnect() invalidating the current node
node = node->GetNext();
- if ((event.GetEventType() == entry->m_eventType) && (entry->m_fn != 0))
+ if ( event.GetEventType() == entry->m_eventType )
{
- wxEvtHandler *handler = entry->m_fn->GetHandler() ? entry->m_fn->GetHandler() : this;
- if ( ProcessEventIfMatches(*entry, handler, event) )
+ wxEvtHandler *handler = entry->m_fn->GetHandler();
+ if ( !handler )
+ handler = this;
+ if ( ProcessEventIfMatchesId(*entry, handler, event) )
return true;
}
}