wxEvtHandler::wxEvtHandler()
{
- m_beingDeleted = false;
-
m_nextHandler = (wxEvtHandler *) NULL;
m_previousHandler = (wxEvtHandler *) NULL;
m_enabled = true;
wxEvtHandler::~wxEvtHandler()
{
- m_beingDeleted = true;
-
// Takes itself out of the list of handlers
if (m_previousHandler)
m_previousHandler->m_nextHandler = m_nextHandler;
wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)*it;
// Remove ourselves from sink destructor notifications
+ // (this has usually been been done, in wxTrackable destructor)
wxEvtHandler *eventSink = entry->m_eventSink;
if ( eventSink )
{
};
if (m_pendingEvents)
- {
- // At this time, we could still be used from other threads.
- // Continue to use sync objects.
- wxENTER_CRIT_SECT( m_pendingEventsLock );
-
m_pendingEvents->DeleteContents(true);
- delete m_pendingEvents;
- m_pendingEvents = NULL;
-
- wxLEAVE_CRIT_SECT( m_pendingEventsLock );
- }
+ delete m_pendingEvents;
// Remove us from wxPendingEvents if necessary.
if ( wxPendingEvents )
{
wxCHECK_RET( event, "NULL event can't be posted" );
- // Catch the situation where destructor is already invoked (in another thread)
- if( m_beingDeleted ) return;
-
// 1) Add this event to our list of pending events
wxENTER_CRIT_SECT( m_pendingEventsLock );
{
wxENTER_CRIT_SECT( m_pendingEventsLock );
- // This method is only called by wxApp if this handler does have
- // pending events, but it happens occasionally when using multi-
- // threading and we don't want a crash due to that.
- if( !m_pendingEvents )
- {
- wxLEAVE_CRIT_SECT( m_pendingEventsLock );
- return;
- }
-
- if( m_pendingEvents->IsEmpty() )
- {
- wxPendingEvents->DeleteObject(this);
- wxLEAVE_CRIT_SECT( m_pendingEventsLock );
- return;
- }
+ // this method is only called by wxApp if this handler does have
+ // pending events
+ wxCHECK_RET( m_pendingEvents && !m_pendingEvents->IsEmpty(),
+ "should have pending events if called" );
wxList::compatibility_iterator node = m_pendingEvents->GetFirst();
wxEventPtr event(wx_static_cast(wxEvent *, node->GetData()));
bool wxEvtHandler::TryParent(wxEvent& event)
{
+ if ( GetNextHandler() )
+ {
+ // the next handler will pass it to wxTheApp if it doesn't process it,
+ // so return from here to avoid doing it again
+ return GetNextHandler()->TryParent(event);
+ }
+
if ( wxTheApp && (this != wxTheApp) )
{
// Special case: don't pass wxEVT_IDLE to wxApp, since it'll always
//else: proceed normally
}
+ if ( ProcessEventHere(event) )
+ return true;
+
+ // 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() )
{
}
// Try going down the event handler chain
- if ( GetNextHandler() )
- {
- // notice that we shouldn't let the parent have the event even if the
- // next handler does not process it because it will have already passed
- // it to the parent in this case
- return GetNextHandler()->ProcessEvent(event);
- }
+ if ( GetNextHandler() && GetNextHandler()->ProcessEventHere(event) )
+ return true;
- // Finally propagate the event upwards the window chain and/or to the
- // application object as necessary
- return TryParent(event);
+ // We don't have a handler for this event.
+ return false;
}
bool wxEvtHandler::SafelyProcessEvent(wxEvent& event)