X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/22b6de6a70900550b5411f14fffc9d48adbbf222..15cac64f7564d48c274c6490774a77bd8c09f808:/src/msw/evtloop.cpp diff --git a/src/msw/evtloop.cpp b/src/msw/evtloop.cpp index f30816d9ce..d09faae69f 100644 --- a/src/msw/evtloop.cpp +++ b/src/msw/evtloop.cpp @@ -32,18 +32,14 @@ #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); @@ -103,6 +99,52 @@ bool wxMSWEventLoopBase::GetNextMessage(WXMSG* msg) 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 @@ -293,6 +335,18 @@ bool wxGUIEventLoop::Dispatch() 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 @@ -309,12 +363,6 @@ void wxGUIEventLoop::WakeUp() #if wxUSE_CONSOLE_EVENTLOOP -void wxConsoleEventLoop::OnNextIteration() -{ - if ( wxTheApp ) - wxTheApp->ProcessPendingEvents(); -} - void wxConsoleEventLoop::WakeUp() { #if wxUSE_THREADS @@ -322,22 +370,39 @@ 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 { - ::DispatchMessage(&msg); + ::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; }