X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/aa8cbe0b64fb84cadf0fbf7da1690a922085ca5f..9af42efda6c78093872a67180d43d5eeba261fee:/src/msw/evtloop.cpp diff --git a/src/msw/evtloop.cpp b/src/msw/evtloop.cpp index 601b8b870b..7c1ab86c19 100644 --- a/src/msw/evtloop.cpp +++ b/src/msw/evtloop.cpp @@ -99,6 +99,41 @@ 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 + if ( ::MsgWaitForMultipleObjects + ( + 0, NULL, + FALSE, + timeout, + QS_ALLINPUT + ) == WAIT_TIMEOUT ) + { + return -1; + } + + if ( !::PeekMessage(msg, 0, 0, 0, PM_REMOVE) ) + { + wxFAIL_MSG( _T("PeekMessage() should have succeeded") ); + + return -1; + } + } + + return msg->message != WM_QUIT; +} + + #endif // wxUSE_BASE #if wxUSE_GUI @@ -289,6 +324,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 @@ -318,22 +365,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; }