X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/14b682f7c36ecf660c2f0bd5c791b8d36d9775f8..e27f554012e20389bb85c7720bf9cb9a1d83cb63:/src/msw/evtloopconsole.cpp diff --git a/src/msw/evtloopconsole.cpp b/src/msw/evtloopconsole.cpp new file mode 100644 index 0000000000..f1538af277 --- /dev/null +++ b/src/msw/evtloopconsole.cpp @@ -0,0 +1,161 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/msw/evtloopconsole.cpp +// Purpose: wxConsoleEventLoop class for Windows +// Author: Vadim Zeitlin +// Modified by: +// Created: 01.06.01 +// RCS-ID: $Id$ +// Copyright: (c) 2001 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/evtloop.h" + +// ============================================================================ +// wxMSWEventLoopBase implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// ctor/dtor +// ---------------------------------------------------------------------------- + +wxMSWEventLoopBase::wxMSWEventLoopBase() +{ + m_shouldExit = false; + m_exitcode = 0; +} + +// ---------------------------------------------------------------------------- +// wxEventLoop message processing dispatching +// ---------------------------------------------------------------------------- + +bool wxMSWEventLoopBase::Pending() const +{ + MSG msg; + return ::PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE) != 0; +} + +bool wxMSWEventLoopBase::GetNextMessage(WXMSG* msg) +{ + const BOOL rc = ::GetMessage(msg, NULL, 0, 0); + + if ( rc == 0 ) + { + // got WM_QUIT + return false; + } + + if ( rc == -1 ) + { + // should never happen, but let's test for it nevertheless + wxLogLastError(wxT("GetMessage")); + + // still break from the loop + return false; + } + + 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; +} + +// ============================================================================ +// wxConsoleEventLoop implementation +// ============================================================================ + +#if wxUSE_CONSOLE_EVENTLOOP + +void wxConsoleEventLoop::WakeUp() +{ +#if wxUSE_THREADS + wxWakeUpMainThread(); +#endif +} + +void wxConsoleEventLoop::ProcessMessage(WXMSG *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; +} + +#endif // wxUSE_CONSOLE_EVENTLOOP