// ============================================================================
wxEventLoop *wxEventLoopBase::ms_activeLoop = NULL;
+wxWindowMSW *wxEventLoop::ms_winCritical = NULL;
// ----------------------------------------------------------------------------
// ctor/dtor
}
}
+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
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
}
// try translations first: the accelerators override everything
- wxWindow *wnd;
-
for ( wnd = wndThis; wnd; wnd = wnd->GetParent() )
{
if ( wnd->MSWTranslateMessage((WXMSG *)msg))
// 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