- // if it wasn't done, dispatch it to the corresponding window
- ::TranslateMessage(msg);
- ::DispatchMessage(msg);
+ // 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;
+ }