X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/924b84ab9461c95cf5c5386d1091ae0f7a8e7ce7..169adfa9c4b781f737920bc808da91cd926c3e36:/src/msw/evtloop.cpp diff --git a/src/msw/evtloop.cpp b/src/msw/evtloop.cpp index 27877fa3f2..54ac1c55cd 100644 --- a/src/msw/evtloop.cpp +++ b/src/msw/evtloop.cpp @@ -17,10 +17,6 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "evtloop.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -49,7 +45,7 @@ #include "wx/listimpl.cpp" - WX_DEFINE_LIST(wxMsgList); + WX_DEFINE_LIST(wxMsgList) #endif // wxUSE_THREADS // ---------------------------------------------------------------------------- @@ -85,6 +81,7 @@ private: // ============================================================================ wxEventLoop *wxEventLoopBase::ms_activeLoop = NULL; +wxWindowMSW *wxEventLoop::ms_winCritical = NULL; // ---------------------------------------------------------------------------- // ctor/dtor @@ -111,10 +108,24 @@ void wxEventLoop::ProcessMessage(WXMSG *msg) } } +bool wxEventLoop::IsChildOfCriticalWindow(wxWindowMSW *win) +{ + while ( win ) + { + if ( win == ms_winCritical ) + return true; + + win = win->GetParent(); + } + + return false; +} + bool wxEventLoop::PreProcessMessage(WXMSG *msg) { HWND hwnd = msg->hwnd; - wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hwnd); + wxWindow * const wndThis = wxGetWindowFromHWND((WXHWND)hwnd); + wxWindow *wnd; // this may happen if the event occurred in a standard modeless dialog (the // only example of which I know of is the find/replace dialog) - then call @@ -132,6 +143,17 @@ bool wxEventLoop::PreProcessMessage(WXMSG *msg) return hwnd && ::IsDialogMessage(hwnd, msg) != 0; } + if ( !AllowProcessing(wndThis) ) + { + // not a child of critical window, so we eat the event but take care to + // stop an endless stream of WM_PAINTs which would have resulted if we + // didn't validate the invalidated part of the window + if ( msg->message == WM_PAINT ) + ::ValidateRect(hwnd, NULL); + + return true; + } + #if wxUSE_TOOLTIPS // we must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to // popup the tooltip bubbles @@ -154,8 +176,6 @@ bool wxEventLoop::PreProcessMessage(WXMSG *msg) } // try translations first: the accelerators override everything - wxWindow *wnd; - for ( wnd = wndThis; wnd; wnd = wnd->GetParent() ) { if ( wnd->MSWTranslateMessage((WXMSG *)msg)) @@ -207,48 +227,74 @@ int wxEventLoop::Run() // should undo wxEventLoopActivator activate(&ms_activeLoop, this); + // we must ensure that OnExit() is called even if an exception is thrown + // from inside Dispatch() but we must call it from Exit() in normal + // situations because it is supposed to be called synchronously, + // wxModalEventLoop depends on this (so we can't just use ON_BLOCK_EXIT or + // something similar here) #if wxUSE_EXCEPTIONS - try + for ( ;; ) { -#endif - // this is the event loop itself - for ( ;; ) + try { - #if wxUSE_THREADS - wxMutexGuiLeaveOrEnter(); - #endif // wxUSE_THREADS - - // generate and process idle events for as long as we don't - // have anything else to do - while ( !Pending() && (wxTheApp && wxTheApp->ProcessIdle()) ) - ; - - // if the "should exit" flag is set, the loop should terminate - // but not before processing any remaining messages so while - // Pending() returns true, do process them - if ( m_shouldExit ) - { - while ( Pending() ) - Dispatch(); +#endif // wxUSE_EXCEPTIONS - break; + // this is the event loop itself + for ( ;; ) + { + #if wxUSE_THREADS + wxMutexGuiLeaveOrEnter(); + #endif // wxUSE_THREADS + + // generate and process idle events for as long as we don't + // have anything else to do + while ( !Pending() && (wxTheApp && wxTheApp->ProcessIdle()) ) + ; + + // if the "should exit" flag is set, the loop should terminate + // but not before processing any remaining messages so while + // Pending() returns true, do process them + if ( m_shouldExit ) + { + while ( Pending() ) + Dispatch(); + + break; + } + + // a message came or no more idle processing to do, sit in + // Dispatch() waiting for the next message + if ( !Dispatch() ) + { + // we got WM_QUIT + break; + } } - // a message came or no more idle processing to do, sit in - // Dispatch() waiting for the next message - if ( !Dispatch() ) +#if wxUSE_EXCEPTIONS + // exit the outer loop as well + break; + } + catch ( ... ) + { + try + { + if ( !wxTheApp || !wxTheApp->OnExceptionInMainLoop() ) + { + OnExit(); + break; + } + //else: continue running the event loop + } + catch ( ... ) { - // we got WM_QUIT - break; + // OnException() throwed, possibly rethrowing the same + // exception again: very good, but we still need OnExit() to + // be called + OnExit(); + throw; } } -#if wxUSE_EXCEPTIONS - } - catch ( ... ) - { - // we need OnExit() to be called before the event loop stops - OnExit(); - throw; } #endif // wxUSE_EXCEPTIONS