- if (!::GetMessage(&s_currentMsg, (HWND) NULL, 0, 0))
- {
- return FALSE;
- }
-
- // Process the message
- if (!ProcessMessage((WXMSG *)&s_currentMsg))
- {
- ::TranslateMessage(&s_currentMsg);
- wxApp::sm_lastMessageTime = s_currentMsg.time; /* MATTHEW: timeStamp impl. */
- ::DispatchMessage(&s_currentMsg);
- }
- return TRUE;
+ BOOL rc = ::GetMessage(&s_currentMsg, (HWND) NULL, 0, 0);
+ if ( rc == 0 )
+ {
+ // got WM_QUIT
+ m_keepGoing = FALSE;
+
+ return FALSE;
+ }
+ else if ( rc == -1 )
+ {
+ // should never happen, but let's test for it nevertheless
+ wxLogLastError("GetMessage");
+ }
+ else
+ {
+#if wxUSE_THREADS
+ wxASSERT_MSG( wxThread::IsMain(),
+ "only the main thread can process Windows messages" );
+
+ static bool s_hadGuiLock = TRUE;
+ static wxMsgArray s_aSavedMessages;
+
+ // if a secondary thread owns is doing GUI calls, save all messages for
+ // later processing - we can't process them right now because it will
+ // lead to recursive library calls (and we're not reentrant)
+ if ( !wxGuiOwnedByMainThread() )
+ {
+ s_hadGuiLock = FALSE;
+
+ // leave out WM_COMMAND messages: too dangerous, sometimes
+ // the message will be processed twice
+ if ( !wxIsWaitingForThread() ||
+ s_currentMsg.message != WM_COMMAND )
+ {
+ s_aSavedMessages.Add(s_currentMsg);
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ // have we just regained the GUI lock? if so, post all of the saved
+ // messages
+ //
+ // FIXME of course, it's not _exactly_ the same as processing the
+ // messages normally - expect some things to break...
+ if ( !s_hadGuiLock )
+ {
+ s_hadGuiLock = TRUE;
+
+ size_t count = s_aSavedMessages.Count();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ MSG& msg = s_aSavedMessages[n];
+
+ if ( !ProcessMessage((WXMSG *)&msg) )
+ {
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+ }
+
+ s_aSavedMessages.Empty();
+ }
+ }
+#endif // wxUSE_THREADS
+
+ // Process the message
+ if ( !ProcessMessage((WXMSG *)&s_currentMsg) )
+ {
+ ::TranslateMessage(&s_currentMsg);
+ wxApp::sm_lastMessageTime = s_currentMsg.time; /* MATTHEW: timeStamp impl. */
+ ::DispatchMessage(&s_currentMsg);
+ }
+ }
+
+ return TRUE;