#endif //WX_PRECOMP
#include "wx/evtloop.h"
-
-
+#include "wx/thread.h"
#include "wx/except.h"
-#include "wx/ptr_scpd.h"
-
#include "wx/msw/private.h"
#if wxUSE_GUI
#include "wx/tooltip.h"
#if wxUSE_THREADS
- #include "wx/thread.h"
-
// define the list of MSG strutures
WX_DECLARE_LIST(MSG, wxMsgList);
return true;
}
+int wxMSWEventLoopBase::GetNextMessageTimeout(WXMSG *msg, unsigned long timeout)
+{
+ // MsgWaitForMultipleObjects() won't notice any input which was already
+ // examined (e.g. using PeekMessage()) but not yet removed from the queue
+ // so we need to remove any immediately messages manually
+ //
+ // NB: using MsgWaitForMultipleObjectsEx() could simplify the code here but
+ // it is not available in very old Windows versions
+ if ( !::PeekMessage(msg, 0, 0, 0, PM_REMOVE) )
+ {
+ // we use this function just in order to not block longer than the
+ // given timeout, so we don't pass any handles to it at all
+ DWORD rc = ::MsgWaitForMultipleObjects
+ (
+ 0, NULL,
+ FALSE,
+ timeout,
+ QS_ALLINPUT
+ );
+
+ switch ( rc )
+ {
+ default:
+ wxLogDebug("unexpected MsgWaitForMultipleObjects() return "
+ "value %lu", rc);
+ // fall through
+
+ case WAIT_TIMEOUT:
+ return -1;
+
+ case WAIT_OBJECT_0:
+ if ( !::PeekMessage(msg, 0, 0, 0, PM_REMOVE) )
+ {
+ // somehow it may happen that MsgWaitForMultipleObjects()
+ // returns true but there are no messages -- just treat it
+ // the same as timeout then
+ return -1;
+ }
+ break;
+ }
+ }
+
+ return msg->message != WM_QUIT;
+}
+
+
#endif // wxUSE_BASE
#if wxUSE_GUI
return true;
}
+int wxGUIEventLoop::DispatchTimeout(unsigned long timeout)
+{
+ MSG msg;
+ int rc = GetNextMessageTimeout(&msg, timeout);
+ if ( rc != 1 )
+ return rc;
+
+ ProcessMessage(&msg);
+
+ return 1;
+}
+
void wxGUIEventLoop::OnNextIteration()
{
#if wxUSE_THREADS
#else // !wxUSE_GUI
-#if wxUSE_CONSOLE_EVENTLOOP
-void wxConsoleEventLoop::OnNextIteration()
-{
- if ( wxTheApp )
- wxTheApp->ProcessPendingEvents();
-}
+// ============================================================================
+// wxConsoleEventLoop implementation
+// ============================================================================
+
+#if wxUSE_CONSOLE_EVENTLOOP
void wxConsoleEventLoop::WakeUp()
{
#endif
}
-bool wxConsoleEventLoop::Dispatch()
+void wxConsoleEventLoop::ProcessMessage(WXMSG *msg)
{
- MSG msg;
- if ( !GetNextMessage(&msg) )
- return false;
-
- if ( msg.message == WM_TIMER )
+ if ( msg->message == WM_TIMER )
{
- TIMERPROC proc = (TIMERPROC)msg.lParam;
+ TIMERPROC proc = (TIMERPROC)msg->lParam;
if ( proc )
- (*proc)(NULL, 0, msg.wParam, 0);
+ (*proc)(NULL, 0, msg->wParam, 0);
}
else
{
- wxLogDebug(_T("Ignoring unexpected message %d"), msg.message);
+ ::DispatchMessage(msg);
}
+}
+
+bool wxConsoleEventLoop::Dispatch()
+{
+ MSG msg;
+ if ( !GetNextMessage(&msg) )
+ return false;
+
+ ProcessMessage(&msg);
+
+ return !m_shouldExit;
+}
+
+int wxConsoleEventLoop::DispatchTimeout(unsigned long timeout)
+{
+ MSG msg;
+ int rc = GetNextMessageTimeout(&msg, timeout);
+ if ( rc != 1 )
+ return rc;
+
+ ProcessMessage(&msg);
return !m_shouldExit;
}