diff --git a/include/wx/app.h b/include/wx/app.h index edd3eef488..3b57e36670 100644 --- a/include/wx/app.h +++ b/include/wx/app.h @@ -32,6 +32,8 @@ class WXDLLIMPEXP_BASE wxCmdLineParser; class WXDLLIMPEXP_BASE wxLog; class WXDLLIMPEXP_BASE wxMessageOutput; +class WXDLLEXPORT wxEventLoop; + // ---------------------------------------------------------------------------- // typedefs // ---------------------------------------------------------------------------- @@ -367,24 +369,27 @@ public: // ----------------------------------------------------------------- // execute the main GUI loop, the function returns when the loop ends - virtual int MainLoop() = 0; + virtual int MainLoop(); // exit the main loop thus terminating the application virtual void Exit(); // exit the main GUI loop during the next iteration (i.e. it does not // stop the program immediately!) - virtual void ExitMainLoop() = 0; + virtual void ExitMainLoop(); - // returns TRUE if the program is initialized + // returns true if the program is initialized, i.e. OnInit() has been + // completed successfully virtual bool Initialized() = 0; // returns TRUE if there are unprocessed events in the event queue - virtual bool Pending() = 0; + virtual bool Pending(); // process the first event in the event queue (blocks until an event - // apperas if there are none currently) - virtual void Dispatch() = 0; + // appears if there are none currently, use Pending() if this is not + // wanted), returns false if the event loop should stop and true + // otherwise + virtual bool Dispatch(); // process all currently pending events right now // @@ -402,7 +407,7 @@ public: // parties // // it should return TRUE if more idle events are needed, FALSE if not - virtual bool ProcessIdle() ; + virtual bool ProcessIdle(); // Send idle event to window and all subwindows // Returns TRUE if more idle time is requested. @@ -493,6 +498,10 @@ protected: virtual wxAppTraits *CreateTraits(); + // the main event loop of the application (may be NULL if the loop hasn't + // been started yet or has already terminated) + wxEventLoop *m_mainLoop; + // the main top level window (may be NULL) wxWindow *m_topWindow; diff --git a/include/wx/cocoa/app.h b/include/wx/cocoa/app.h index 6095a8eb34..d114405049 100644 --- a/include/wx/cocoa/app.h +++ b/include/wx/cocoa/app.h @@ -50,7 +50,7 @@ public: virtual void ExitMainLoop(); virtual bool Initialized(); virtual bool Pending(); - virtual void Dispatch(); + virtual bool Dispatch(); virtual void Exit(); diff --git a/include/wx/gtk/app.h b/include/wx/gtk/app.h index ac03484769..ad1496c967 100644 --- a/include/wx/gtk/app.h +++ b/include/wx/gtk/app.h @@ -45,7 +45,7 @@ public: virtual void ExitMainLoop(); virtual bool Initialized(); virtual bool Pending(); - virtual void Dispatch(); + virtual bool Dispatch(); virtual void Exit(); diff --git a/include/wx/gtk1/app.h b/include/wx/gtk1/app.h index ac03484769..ad1496c967 100644 --- a/include/wx/gtk1/app.h +++ b/include/wx/gtk1/app.h @@ -45,7 +45,7 @@ public: virtual void ExitMainLoop(); virtual bool Initialized(); virtual bool Pending(); - virtual void Dispatch(); + virtual bool Dispatch(); virtual void Exit(); diff --git a/include/wx/mac/app.h b/include/wx/mac/app.h index fc560f1561..e65ee6ec2f 100644 --- a/include/wx/mac/app.h +++ b/include/wx/mac/app.h @@ -51,7 +51,7 @@ class WXDLLEXPORT wxApp: public wxAppBase virtual void ExitMainLoop(); virtual bool Initialized(); virtual bool Pending() ; - virtual void Dispatch() ; + virtual bool Dispatch() ; virtual void Exit(); diff --git a/include/wx/mgl/app.h b/include/wx/mgl/app.h index c400519cfb..c1e6aca517 100644 --- a/include/wx/mgl/app.h +++ b/include/wx/mgl/app.h @@ -42,11 +42,7 @@ public: virtual bool OnInitGui(); // override base class (pure) virtuals - virtual int MainLoop(); - virtual void ExitMainLoop(); virtual bool Initialized(); - virtual bool Pending(); - virtual void Dispatch(); virtual bool Initialize(int& argc, wxChar **argv); virtual void CleanUp(); @@ -59,8 +55,7 @@ public: private: DECLARE_DYNAMIC_CLASS(wxApp) DECLARE_EVENT_TABLE() - - wxEventLoop *m_mainLoop; + wxDisplayModeInfo m_displayMode; }; diff --git a/include/wx/motif/app.h b/include/wx/motif/app.h index 9a2526a1f1..893423b3c0 100644 --- a/include/wx/motif/app.h +++ b/include/wx/motif/app.h @@ -53,8 +53,6 @@ public: virtual int MainLoop(); virtual void ExitMainLoop(); virtual bool Initialized(); - virtual bool Pending(); - virtual void Dispatch(); virtual void Exit(); diff --git a/include/wx/msw/app.h b/include/wx/msw/app.h index e73040eded..835fdf8afd 100644 --- a/include/wx/msw/app.h +++ b/include/wx/msw/app.h @@ -39,11 +39,7 @@ public: virtual bool Initialize(int& argc, wxChar **argv); virtual void CleanUp(); - virtual int MainLoop(); - virtual void ExitMainLoop(); virtual bool Initialized(); - virtual bool Pending(); - virtual void Dispatch(); virtual bool Yield(bool onlyIfNeeded = FALSE); virtual void WakeUpIdle(); @@ -67,18 +63,6 @@ public: static bool RegisterWindowClasses(); static bool UnregisterWindowClasses(); - // message processing - // ------------------ - - // process the given message - virtual void DoMessage(WXMSG *pMsg); - - // retrieve the next message from the queue and process it - virtual bool DoMessage(); - - // preprocess the message - virtual bool ProcessMessage(WXMSG* pMsg); - // idle processing // --------------- @@ -98,9 +82,6 @@ public: static int m_nCmdShow; protected: - // we exit the main event loop when this flag becomes false - bool m_keepGoing; - DECLARE_EVENT_TABLE() DECLARE_NO_COPY_CLASS(wxApp) }; diff --git a/include/wx/os2/app.h b/include/wx/os2/app.h index 4a4312085d..c7cc54efbc 100644 --- a/include/wx/os2/app.h +++ b/include/wx/os2/app.h @@ -75,7 +75,7 @@ public: virtual void ExitMainLoop(void); virtual bool Initialized(void); virtual bool Pending(void) ; - virtual void Dispatch(void); + virtual bool Dispatch(void); virtual void Exit(); diff --git a/include/wx/x11/app.h b/include/wx/x11/app.h index fb7e97cffc..4c14323209 100644 --- a/include/wx/x11/app.h +++ b/include/wx/x11/app.h @@ -32,7 +32,6 @@ class WXDLLEXPORT wxWindow; class WXDLLEXPORT wxApp; class WXDLLEXPORT wxKeyEvent; class WXDLLEXPORT wxLog; -class WXDLLEXPORT wxEventLoop; class WXDLLEXPORT wxXVisualInfo; // ---------------------------------------------------------------------------- @@ -42,14 +41,14 @@ class WXDLLEXPORT wxXVisualInfo; class WXDLLEXPORT wxApp : public wxAppBase { DECLARE_DYNAMIC_CLASS(wxApp) - + public: wxApp(); ~wxApp(); - + // override base class (pure) virtuals // ----------------------------------- - + virtual int MainLoop(); virtual void ExitMainLoop(); virtual bool Initialized(); @@ -60,45 +59,45 @@ public: virtual bool Yield(bool onlyIfNeeded = FALSE); virtual void WakeUpIdle(); - + virtual bool OnInitGui(); - + // implementation from now on // -------------------------- - + // Processes an X event. virtual bool ProcessXEvent(WXEvent* event); - + #ifdef __WXDEBUG__ virtual void OnAssert(const wxChar *file, int line, const wxChar* cond, const wxChar *msg); #endif // __WXDEBUG__ - + protected: bool m_showOnInit; - + public: // Implementation virtual bool Initialize(int& argc, wxChar **argv); virtual void CleanUp(); - + WXWindow GetTopLevelWidget() const { return m_topLevelWidget; } WXColormap GetMainColormap(WXDisplay* display); long GetMaxRequestSize() const { return m_maxRequestSize; } - + // This handler is called when a property change event occurs virtual bool HandlePropertyChange(WXEvent *event); - + // Values that can be passed on the command line. // Returns -1, -1 if none specified. const wxSize& GetInitialSize() const { return m_initialSize; } bool GetShowIconic() const { return m_showIconic; } - + #if wxUSE_UNICODE // Global context for Pango layout. Either use X11 // or use Xft rendering according to GDK_USE_XFT // environment variable PangoContext* GetPangoContext(); -#endif +#endif wxXVisualInfo* GetVisualInfo(WXDisplay* display) { @@ -113,21 +112,20 @@ public: public: static long sm_lastMessageTime; - bool m_showIconic; + bool m_showIconic; wxSize m_initialSize; #if !wxUSE_NANOX wxXVisualInfo* m_visualInfo; #endif - + protected: bool m_keepGoing; - + WXWindow m_topLevelWidget; WXColormap m_mainColormap; long m_maxRequestSize; - wxEventLoop* m_mainLoop; - + DECLARE_EVENT_TABLE() }; diff --git a/src/cocoa/app.mm b/src/cocoa/app.mm index 92684dafc9..1436da767d 100644 --- a/src/cocoa/app.mm +++ b/src/cocoa/app.mm @@ -273,8 +273,9 @@ bool wxApp::Pending() } // Dispatch a message. -void wxApp::Dispatch() +bool wxApp::Dispatch() { + return true; } // Yield to other processes diff --git a/src/common/appcmn.cpp b/src/common/appcmn.cpp index 5c19be543e..7bb2873177 100644 --- a/src/common/appcmn.cpp +++ b/src/common/appcmn.cpp @@ -41,9 +41,11 @@ #include "wx/apptrait.h" #include "wx/cmdline.h" +#include "wx/evtloop.h" #include "wx/msgout.h" #include "wx/thread.h" #include "wx/utils.h" +#include "wx/ptr_scpd.h" #if defined(__WXMSW__) #include "wx/msw/private.h" // includes windows.h for LOGFONT @@ -57,6 +59,30 @@ #include "wx/build.h" WX_CHECK_BUILD_OPTIONS("wxCore") + +// ---------------------------------------------------------------------------- +// wxEventLoopPtr +// ---------------------------------------------------------------------------- + +// this defines wxEventLoopPtr +wxDEFINE_SCOPED_PTR_TYPE(wxEventLoop); + +// but we need a smart pointer tied to wxAppBase::m_mainLoop, so we define +// another helper class +class wxTiedEventLoopPtr : public wxEventLoopPtr +{ +public: + wxTiedEventLoopPtr(wxEventLoop **ppEvtLoop, wxEventLoop *pLoop) + : wxEventLoopPtr(*ppEvtLoop = pLoop), m_ppEvtLoop(ppEvtLoop) + { + } + + ~wxTiedEventLoopPtr() { *m_ppEvtLoop = NULL; } + +private: + wxEventLoop **m_ppEvtLoop; +}; + // ============================================================================ // wxAppBase implementation // ============================================================================ @@ -71,6 +97,8 @@ wxAppBase::wxAppBase() m_useBestVisual = FALSE; m_isActive = TRUE; + m_mainLoop = NULL; + // We don't want to exit the app if the user code shows a dialog from its // OnInit() -- but this is what would happen if we set m_exitOnFrameDelete // to Yes initially as this dialog would be the last top level window. @@ -236,6 +264,45 @@ bool wxAppBase::OnCmdLineParsed(wxCmdLineParser& parser) #endif // wxUSE_CMDLINE_PARSER +// ---------------------------------------------------------------------------- +// main event loop implementation +// ---------------------------------------------------------------------------- + +int wxAppBase::MainLoop() +{ + wxTiedEventLoopPtr mainLoop(&m_mainLoop, new wxEventLoop); + + return m_mainLoop->Run(); +} + +void wxAppBase::ExitMainLoop() +{ + // we should exit from the main event loop, not just any currently active + // (e.g. modal dialog) event loop + if ( m_mainLoop ) + { + m_mainLoop->Exit(0); + } +} + +bool wxAppBase::Pending() +{ + // use the currently active message loop here, not m_mainLoop, because if + // we're showing a modal dialog (with its own event loop) currently the + // main event loop is not running anyhow + wxEventLoop * const loop = wxEventLoop::GetActive(); + + return loop && loop->Pending(); +} + +bool wxAppBase::Dispatch() +{ + // see comment in Pending() + wxEventLoop * const loop = wxEventLoop::GetActive(); + + return loop ? loop->Dispatch() : true; +} + // ---------------------------------------------------------------------------- // OnXXX() hooks // ---------------------------------------------------------------------------- diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index e58a9c8e97..21748cb2e9 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -567,9 +567,11 @@ bool wxApp::Pending() return (gtk_events_pending() > 0); } -void wxApp::Dispatch() +bool wxApp::Dispatch() { gtk_main_iteration(); + + return true; } bool wxApp::Initialize(int& argc, wxChar **argv) diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp index e58a9c8e97..21748cb2e9 100644 --- a/src/gtk1/app.cpp +++ b/src/gtk1/app.cpp @@ -567,9 +567,11 @@ bool wxApp::Pending() return (gtk_events_pending() > 0); } -void wxApp::Dispatch() +bool wxApp::Dispatch() { gtk_main_iteration(); + + return true; } bool wxApp::Initialize(int& argc, wxChar **argv) diff --git a/src/mac/app.cpp b/src/mac/app.cpp index 90ff659bcb..3a18d6363f 100644 --- a/src/mac/app.cpp +++ b/src/mac/app.cpp @@ -1049,9 +1049,11 @@ bool wxApp::Pending() } // Dispatch a message. -void wxApp::Dispatch() +bool wxApp::Dispatch() { MacDoOneEvent() ; + + return true; } void wxApp::OnIdle(wxIdleEvent& event) diff --git a/src/mac/carbon/app.cpp b/src/mac/carbon/app.cpp index 90ff659bcb..3a18d6363f 100644 --- a/src/mac/carbon/app.cpp +++ b/src/mac/carbon/app.cpp @@ -1049,9 +1049,11 @@ bool wxApp::Pending() } // Dispatch a message. -void wxApp::Dispatch() +bool wxApp::Dispatch() { MacDoOneEvent() ; + + return true; } void wxApp::OnIdle(wxIdleEvent& event) diff --git a/src/mgl/app.cpp b/src/mgl/app.cpp index df6d37aa0e..d92b40c293 100644 --- a/src/mgl/app.cpp +++ b/src/mgl/app.cpp @@ -272,37 +272,9 @@ bool wxApp::OnInitGui() return TRUE; } -int wxApp::MainLoop() -{ - int rt; - m_mainLoop = new wxEventLoop; - - rt = m_mainLoop->Run(); - - delete m_mainLoop; - m_mainLoop = NULL; - return rt; -} - -void wxApp::ExitMainLoop() -{ - if ( m_mainLoop ) - m_mainLoop->Exit(0); -} - bool wxApp::Initialized() { - return (wxTopLevelWindows.GetCount() != 0); -} - -bool wxApp::Pending() -{ - return wxEventLoop::GetActive()->Pending(); -} - -void wxApp::Dispatch() -{ - wxEventLoop::GetActive()->Dispatch(); + return wxTopLevelWindows.GetCount() != 0; } bool wxApp::Initialize(int& argc, wxChar **argv) diff --git a/src/motif/app.cpp b/src/motif/app.cpp index 0641c9878e..9c202c14b1 100644 --- a/src/motif/app.cpp +++ b/src/motif/app.cpp @@ -176,25 +176,6 @@ void wxApp::ExitMainLoop() m_eventLoop->Exit(); } -// Is a message/event pending? -bool wxApp::Pending() -{ - return m_eventLoop->Pending(); -#if 0 - XFlush(XtDisplay( (Widget) wxTheApp->GetTopLevelWidget() )); - - // Fix by Doug from STI, to prevent a stall if non-X event - // is found. - return ((XtAppPending( (XtAppContext) GetAppContext() ) & XtIMXEvent) != 0) ; -#endif -} - -// Dispatch a message. -void wxApp::Dispatch() -{ - m_eventLoop->Dispatch(); -} - // This should be redefined in a derived class for // handling property change events for XAtom IPC. void wxApp::HandlePropertyChange(WXEvent *event) diff --git a/src/msw/app.cpp b/src/msw/app.cpp index ec3c4c0124..1176d193a3 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -89,7 +89,7 @@ #if (!defined(__MINGW32__) || wxCHECK_W32API_VERSION( 2, 0 )) && \ !defined(__CYGWIN__) && !defined(__DIGITALMARS__) && !defined(__WXWINCE__) && \ - (!defined(_MSC_VER) || (_MSC_VER > 1100)) + (!defined(_MSC_VER) || (_MSC_VER > 1100)) #include #endif @@ -103,8 +103,6 @@ extern wxList WXDLLEXPORT wxPendingDelete; extern void wxSetKeyboardHook(bool doIt); #endif -MSG s_currentMsg; - // NB: all "NoRedraw" classes must have the same names as the "normal" classes // with NR suffix - wxWindow::MSWCreate() supposes this const wxChar *wxCanvasClassName = wxT("wxWindowClass"); @@ -200,12 +198,14 @@ void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig) bool wxGUIAppTraits::DoMessageFromThreadWait() { - return !wxTheApp || wxTheApp->DoMessage(); + // we should return false only if the app should exit, i.e. only if + // Dispatch() determines that the main event loop should terminate + return !wxTheApp || wxTheApp->Dispatch(); } wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo() { - static wxToolkitInfo info; + static wxToolkitInfo info; wxToolkitInfo& baseInfo = wxAppTraits::GetToolkitInfo(); info.versionMajor = baseInfo.versionMajor; info.versionMinor = baseInfo.versionMinor; @@ -568,219 +568,6 @@ bool wxApp::Initialized() #endif } -/* - * Get and process a message, returning FALSE if WM_QUIT - * received (and also set the flag telling the app to exit the main loop) - * - */ -bool wxApp::DoMessage() -{ - 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(wxT("GetMessage")); - } - else - { -#if wxUSE_THREADS - wxASSERT_MSG( wxThread::IsMain(), - wxT("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.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - MSG& msg = s_aSavedMessages[n]; - - DoMessage((WXMSG *)&msg); - } - - s_aSavedMessages.Empty(); - } - } -#endif // wxUSE_THREADS - - // Process the message - DoMessage((WXMSG *)&s_currentMsg); - } - - return TRUE; -} - -void wxApp::DoMessage(WXMSG *pMsg) -{ - if ( !ProcessMessage(pMsg) ) - { - ::TranslateMessage((MSG *)pMsg); - ::DispatchMessage((MSG *)pMsg); - } -} - -/* - * Keep trying to process messages until WM_QUIT - * received. - * - * If there are messages to be processed, they will all be - * processed and OnIdle will not be called. - * When there are no more messages, OnIdle is called. - * If OnIdle requests more time, - * it will be repeatedly called so long as there are no pending messages. - * A 'feature' of this is that once OnIdle has decided that no more processing - * is required, then it won't get processing time until further messages - * are processed (it'll sit in DoMessage). - */ - -int wxApp::MainLoop() -{ - m_keepGoing = TRUE; - - while ( m_keepGoing ) - { -#if wxUSE_THREADS - wxMutexGuiLeaveOrEnter(); -#endif // wxUSE_THREADS - - while ( !Pending() && ProcessIdle() ) - ; - - // a message came or no more idle processing to do - DoMessage(); - } - - return s_currentMsg.wParam; -} - -void wxApp::ExitMainLoop() -{ - // this will set m_keepGoing to FALSE a bit later - ::PostQuitMessage(0); -} - -bool wxApp::Pending() -{ - return ::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) != 0; -} - -void wxApp::Dispatch() -{ - DoMessage(); -} - -/* - * Give all windows a chance to preprocess - * the message. Some may have accelerator tables, or have - * MDI complications. - */ - -bool wxApp::ProcessMessage(WXMSG *wxmsg) -{ - MSG *msg = (MSG *)wxmsg; - HWND hwnd = msg->hwnd; - wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hwnd); - - // this may happen if the event occured in a standard modeless dialog (the - // only example of which I know of is the find/replace dialog) - then call - // IsDialogMessage() to make TAB navigation in it work - if ( !wndThis ) - { - // we need to find the dialog containing this control as - // IsDialogMessage() just eats all the messages (i.e. returns TRUE for - // them) if we call it for the control itself - while ( hwnd && ::GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD ) - { - hwnd = ::GetParent(hwnd); - } - - return hwnd && ::IsDialogMessage(hwnd, msg) != 0; - } - -#if wxUSE_TOOLTIPS - // we must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to - // popup the tooltip bubbles - if ( (msg->message == WM_MOUSEMOVE) ) - { - wxToolTip *tt = wndThis->GetToolTip(); - if ( tt ) - { - tt->RelayEvent(wxmsg); - } - } -#endif // wxUSE_TOOLTIPS - - // allow the window to prevent certain messages from being - // translated/processed (this is currently used by wxTextCtrl to always - // grab Ctrl-C/V/X, even if they are also accelerators in some parent) - if ( !wndThis->MSWShouldPreProcessMessage(wxmsg) ) - { - return FALSE; - } - - // try translations first: the accelerators override everything - wxWindow *wnd; - - for ( wnd = wndThis; wnd; wnd = wnd->GetParent() ) - { - if ( wnd->MSWTranslateMessage(wxmsg)) - return TRUE; - - // stop at first top level window, i.e. don't try to process the key - // strokes originating in a dialog using the accelerators of the parent - // frame - this doesn't make much sense - if ( wnd->IsTopLevel() ) - break; - } - - // now try the other hooks (kbd navigation is handled here): we start from - // wndThis->GetParent() because wndThis->MSWProcessMessage() was already - // called above - for ( wnd = wndThis->GetParent(); wnd; wnd = wnd->GetParent() ) - { - if ( wnd->MSWProcessMessage(wxmsg) ) - return TRUE; - } - - // no special preprocessing for this message, dispatch it normally - return FALSE; -} - // this is a temporary hack and will be replaced by using wxEventLoop in the // future // @@ -796,7 +583,7 @@ void wxApp::OnIdle(wxIdleEvent& event) return; wxIsInOnIdleFlag = TRUE; - + wxAppBase::OnIdle(event); #if wxUSE_DC_CACHEING @@ -965,7 +752,7 @@ bool wxApp::Yield(bool onlyIfNeeded) wxMutexGuiLeaveOrEnter(); #endif // wxUSE_THREADS - if ( !wxTheApp->DoMessage() ) + if ( !wxTheApp->Dispatch() ) break; } diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 598b077b1a..d20cd3d9e6 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -162,9 +162,6 @@ // global variables // --------------------------------------------------------------------------- -// the last Windows message we got (FIXME-MT) -extern MSG s_currentMsg; - #if wxUSE_MENUS_NATIVE wxMenu *wxCurrentPopupMenu = NULL; #endif // wxUSE_MENUS_NATIVE @@ -1750,15 +1747,21 @@ static void wxYieldForCommandsOnly() // peek all WM_COMMANDs (it will always return WM_QUIT too but we don't // want to process it here) MSG msg; - while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE) - && msg.message != WM_QUIT ) + while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE) ) { - wxTheApp->DoMessage((WXMSG *)&msg); - } + if ( msg.message != WM_QUIT ) + { + // if we retrieved a WM_QUIT, insert back into the message queue. + ::PostQuitMessage(0); + break; + } - // If we retrieved a WM_QUIT, insert back into the message queue. - if (msg.message == WM_QUIT) - ::PostQuitMessage(0); + // luckily (as we don't have access to wxEventLoopImpl method from here + // anyhow...) we don't need to pre process WM_COMMANDs so dispatch it + // immediately + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } } bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) @@ -4220,7 +4223,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event, // so simply test for negative value. event.m_altDown = ::GetKeyState(VK_MENU) < 0; - event.SetTimestamp(s_currentMsg.time); + event.SetTimestamp(::GetMessageTime()); event.m_eventObject = this; event.SetId(GetId()); @@ -4418,7 +4421,7 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType, event.m_keyCode = id; event.m_rawCode = (wxUint32) wParam; event.m_rawFlags = (wxUint32) lParam; - event.SetTimestamp(s_currentMsg.time); + event.SetTimestamp(::GetMessageTime()); // translate the position to client coords POINT pt; @@ -5092,7 +5095,7 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) event.m_keyCode = id; event.m_shiftDown = wxIsShiftDown(); event.m_controlDown = wxIsCtrlDown(); - event.SetTimestamp(s_currentMsg.time); + event.SetTimestamp(::GetMessageTime()); wxWindow *win = wxGetActiveWindow(); wxEvtHandler *handler;