#endif // !USE_SHARED_LIBRARY
+#if wxUSE_THREADS
+/* To put pending event handlers */
+extern wxList wxPendingEvents;
+extern wxCriticalSection wxPendingEventsLocker;
+#endif
+
/*
* General wxWindows events, covering
* all interesting things that might happen (button clicking, resizing,
m_id = theId;
m_skipped = FALSE;
m_callbackUserData = (wxObject *) NULL;
+ m_isCommandEvent = FALSE;
}
/*
m_commandInt = 0;
m_id = theId;
m_commandString = (char *) NULL;
+ m_isCommandEvent = TRUE;
}
/*
m_previousHandler = (wxEvtHandler *) NULL;
m_enabled = TRUE;
m_dynamicEvents = (wxList *) NULL;
+ m_isWindow = FALSE;
+#if wxUSE_THREADS
+ m_eventsLocker = new wxCriticalSection();
+#endif
+ m_pendingEvents = (wxList *) NULL;
}
wxEvtHandler::~wxEvtHandler()
}
delete m_dynamicEvents;
};
+
+ if (m_pendingEvents)
+ delete m_pendingEvents;
+
+#if wxUSE_THREADS
+ delete m_eventsLocker;
+#endif
+}
+
+#if wxUSE_THREADS
+bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
+{
+ wxEvent *event_main;
+ wxCriticalSectionLocker locker(*m_eventsLocker);
+
+ // check that we are really in a child thread
+ wxASSERT( !wxThread::IsMain() );
+
+ if (m_pendingEvents == NULL)
+ m_pendingEvents = new wxList();
+
+ event_main = (wxEvent *)event.GetClassInfo()->CreateObject();
+ *event_main = event;
+
+ m_pendingEvents->Append(event_main);
+
+ wxPendingEventsLocker.Enter();
+ wxPendingEvents.Append(this);
+ wxPendingEventsLocker.Leave();
+
+ return TRUE;
}
+void wxEvtHandler::ProcessPendingEvents()
+{
+ wxCriticalSectionLocker locker(*m_eventsLocker);
+ wxNode *node = m_pendingEvents->First();
+ wxEvent *event;
+
+ while (node != NULL) {
+ event = (wxEvent *)node->Data();
+ ProcessEvent(*event);
+ delete node;
+ node = m_pendingEvents->First();
+ }
+}
+#endif
+
/*
* Event table stuff
*/
bool wxEvtHandler::ProcessEvent(wxEvent& event)
{
- bool isWindow = IsKindOf(CLASSINFO(wxWindow));
+ // check that our flag corresponds to reality
+ wxASSERT( m_isWindow == IsKindOf(CLASSINFO(wxWindow)) );
// An event handler can be enabled or disabled
if ( GetEvtHandlerEnabled() )
{
+#if wxUSE_THREADS
+ // Check whether we are in a child thread.
+ if (!wxThread::IsMain())
+ return ProcessThreadEvent(event);
+#endif
// Handle per-instance dynamic event tables first
- if (SearchDynamicEventTable( event ))
+ if ( m_dynamicEvents && SearchDynamicEventTable(event) )
return TRUE;
// Then static per-class event tables
// THIS CAN BE CURED if PushEventHandler is used instead of
// SetEventHandler, and then processing will be passed down the
// chain of event handlers.
- if ( isWindow )
+ if ( m_isWindow )
{
wxWindow *win = (wxWindow *)this;
// Can only use the validator of the window which
// is receiving the event
- if ( (win == event.GetEventObject()) &&
- win->GetValidator() &&
- win->GetValidator()->ProcessEvent(event))
+ if ( win == event.GetEventObject() )
{
- return TRUE;
+ wxValidator *validator = win->GetValidator();
+ if ( validator && validator->ProcessEvent(event) )
+ {
+ return TRUE;
+ }
}
}
// Search upwards through the inheritance hierarchy
- while (table)
+ while ( table )
{
- if (SearchEventTable((wxEventTable&)*table, event))
+ if ( SearchEventTable((wxEventTable&)*table, event) )
return TRUE;
table = table->baseTable;
}
// Carry on up the parent-child hierarchy,
// but only if event is a command event: it wouldn't
// make sense for a parent to receive a child's size event, for example
- if ( isWindow && event.IsKindOf(CLASSINFO(wxCommandEvent)) )
+ if ( m_isWindow && event.IsCommandEvent() )
{
wxWindow *win = (wxWindow *)this;
wxWindow *parent = win->GetParent();
if (parent && !parent->IsBeingDeleted())
- return win->GetParent()->GetEventHandler()->ProcessEvent(event);
+ return parent->GetEventHandler()->ProcessEvent(event);
}
// Last try - application object.
- // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always swallow
- // it. wxEVT_IDLE is sent explicitly to wxApp so it will be processed
- // appropriately via SearchEventTable.
- if ( wxTheApp && (this != wxTheApp) && (event.GetEventType() != wxEVT_IDLE)
- )
+ if ( wxTheApp && (this != wxTheApp) )
{
- if ( wxTheApp->ProcessEvent(event) )
- return TRUE;
+ // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always
+ // swallow it. wxEVT_IDLE is sent explicitly to wxApp so it will be
+ // processed appropriately via SearchEventTable.
+ if ( event.GetEventType() != wxEVT_IDLE )
+ {
+ if ( wxTheApp->ProcessEvent(event) )
+ return TRUE;
+ }
}
return FALSE;
// BC++ doesn't like while (table.entries[i].m_fn)
+#ifdef __SC__
+ while (table.entries[i].m_fn != 0)
+#else
while (table.entries[i].m_fn != 0L)
+#endif
{
if ((event.GetEventType() == table.entries[i].m_eventType) &&
(table.entries[i].m_id == -1 || // Match, if event spec says any id will do (id == -1)
}
return FALSE;
}
-
void wxEvtHandler::Connect( int id, int lastId,
wxEventType eventType,
wxObjectEventFunction func,
bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event )
{
- if (!m_dynamicEvents) return FALSE;
+ wxCHECK_MSG( m_dynamicEvents, FALSE,
+ "caller should check that we have dynamic events" );
int commandId = event.GetId();
return FALSE;
};
+#if WXWIN_COMPATIBILITY
bool wxEvtHandler::OnClose()
{
if (GetNextHandler())
else
return FALSE;
}
+#endif // WXWIN_COMPATIBILITY
+