#pragma interface "evtloop.h"
#endif
+class WXDLLEXPORT wxEventLoopImpl;
+
// ----------------------------------------------------------------------------
// wxEventLoop: a GUI event loop
// ----------------------------------------------------------------------------
static void SetActive(wxEventLoop* loop) { ms_activeLoop = loop; }
protected:
- // the pointer to the port specific implementation class
- class WXDLLEXPORT wxEventLoopImpl *m_impl;
+ // this function should be called before the event loop terminates, whether
+ // this happens normally (because of Exit() call) or abnormally (because of
+ // an exception thrown from inside the loop)
+ virtual void OnExit() { }
+
+
// the pointer to currently active loop
static wxEventLoop *ms_activeLoop;
+ // the pointer to the port specific implementation class
+ wxEventLoopImpl *m_impl;
+
DECLARE_NO_COPY_CLASS(wxEventLoop)
};
+// ----------------------------------------------------------------------------
+// wxModalEventLoop
+// ----------------------------------------------------------------------------
+
+// this is a naive generic implementation which uses wxWindowDisabler to
+// implement modality, we will surely need platform-specific implementations
+// too, this generic implementation is here only temporarily to see how it
+// works
+class WXDLLEXPORT wxModalEventLoop : public wxEventLoop
+{
+public:
+ wxModalEventLoop(wxWindow *winModal)
+ {
+ m_windowDisabler = new wxWindowDisabler(winModal);
+ }
+
+protected:
+ virtual void OnExit()
+ {
+ delete m_windowDisabler;
+ m_windowDisabler = NULL;
+
+ wxEventLoop::OnExit();
+ }
+
+private:
+ wxWindowDisabler *m_windowDisabler;
+};
+
#endif // _WX_EVTLOOP_H_
#endif //WX_PRECOMP
#include "wx/evtloop.h"
+
#include "wx/tooltip.h"
+#include "wx/except.h"
+#include "wx/ptr_scpd.h"
+#include "wx/scopeguard.h"
#include "wx/msw/private.h"
#if wxUSE_THREADS
+ #include "wx/thread.h"
+
// define the array of MSG strutures
WX_DECLARE_OBJARRAY(MSG, wxMsgArray);
- // VS: this is a bit dirty - it duplicates same declaration in app.cpp
- // (and there's no WX_DEFINE_OBJARRAY for that reason - it is already
- // defined in app.cpp).
-#endif
+
+ #include "wx/arrimpl.cpp"
+
+ WX_DEFINE_OBJARRAY(wxMsgArray);
+#endif // wxUSE_THREADS
// ----------------------------------------------------------------------------
// wxEventLoopImpl
int m_exitcode;
};
+// ----------------------------------------------------------------------------
+// helper class
+// ----------------------------------------------------------------------------
+
+wxDEFINE_TIED_SCOPED_PTR_TYPE(wxEventLoopImpl);
+
+// this object sets the wxEventLoop given to the ctor as the currently active
+// one and unsets it in its dtor
+class wxEventLoopActivator
+{
+public:
+ wxEventLoopActivator(wxEventLoop **pActive,
+ wxEventLoop *evtLoop)
+ {
+ m_pActive = pActive;
+ m_evtLoopOld = *pActive;
+ *pActive = evtLoop;
+ }
+
+ ~wxEventLoopActivator()
+ {
+ // restore the previously active event loop
+ *m_pActive = m_evtLoopOld;
+ }
+
+private:
+ wxEventLoop *m_evtLoopOld;
+ wxEventLoop **m_pActive;
+};
+
// ============================================================================
// wxEventLoopImpl implementation
// ============================================================================
// event loops are not recursive, you need to create another loop!
wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
- m_impl = new wxEventLoopImpl;
-
- wxEventLoop *oldLoop = ms_activeLoop;
- ms_activeLoop = this;
+ // SendIdleMessage() and Dispatch() below may throw so the code here should
+ // be exception-safe, hence we must use local objects for all actions we
+ // should undo
+ wxEventLoopActivator activate(&ms_activeLoop, this);
+ wxEventLoopImplTiedPtr impl(&m_impl, new wxEventLoopImpl);
+
+ wxON_BLOCK_EXIT_OBJ0(*this, &wxEventLoop::OnExit);
for ( ;; )
{
while ( !Pending() && m_impl->SendIdleMessage() )
;
- // a message came or no more idle processing to do, sit in Dispatch()
- // waiting for the next message
+ // a message came or no more idle processing to do, sit in
+ // Dispatch() waiting for the next message
if ( !Dispatch() )
{
// we got WM_QUIT
}
}
- int exitcode = m_impl->GetExitCode();
- delete m_impl;
- m_impl = NULL;
-
- ms_activeLoop = oldLoop;
-
- return exitcode;
+ return m_impl->GetExitCode();
}
void wxEventLoop::Exit(int rc)