added OnExit(); made event loop exception safe; added wxModalEvtLoop
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23647 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
#pragma interface "evtloop.h"
|
#pragma interface "evtloop.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxEventLoopImpl;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxEventLoop: a GUI event loop
|
// wxEventLoop: a GUI event loop
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -51,12 +53,48 @@ public:
|
|||||||
static void SetActive(wxEventLoop* loop) { ms_activeLoop = loop; }
|
static void SetActive(wxEventLoop* loop) { ms_activeLoop = loop; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// the pointer to the port specific implementation class
|
// this function should be called before the event loop terminates, whether
|
||||||
class WXDLLEXPORT wxEventLoopImpl *m_impl;
|
// 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
|
// the pointer to currently active loop
|
||||||
static wxEventLoop *ms_activeLoop;
|
static wxEventLoop *ms_activeLoop;
|
||||||
|
|
||||||
|
// the pointer to the port specific implementation class
|
||||||
|
wxEventLoopImpl *m_impl;
|
||||||
|
|
||||||
DECLARE_NO_COPY_CLASS(wxEventLoop)
|
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_EVTLOOP_H_
|
||||||
|
@@ -34,17 +34,24 @@
|
|||||||
#endif //WX_PRECOMP
|
#endif //WX_PRECOMP
|
||||||
|
|
||||||
#include "wx/evtloop.h"
|
#include "wx/evtloop.h"
|
||||||
|
|
||||||
#include "wx/tooltip.h"
|
#include "wx/tooltip.h"
|
||||||
|
#include "wx/except.h"
|
||||||
|
#include "wx/ptr_scpd.h"
|
||||||
|
#include "wx/scopeguard.h"
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
|
||||||
#if wxUSE_THREADS
|
#if wxUSE_THREADS
|
||||||
|
#include "wx/thread.h"
|
||||||
|
|
||||||
// define the array of MSG strutures
|
// define the array of MSG strutures
|
||||||
WX_DECLARE_OBJARRAY(MSG, wxMsgArray);
|
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
|
#include "wx/arrimpl.cpp"
|
||||||
// defined in app.cpp).
|
|
||||||
#endif
|
WX_DEFINE_OBJARRAY(wxMsgArray);
|
||||||
|
#endif // wxUSE_THREADS
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxEventLoopImpl
|
// wxEventLoopImpl
|
||||||
@@ -75,6 +82,36 @@ private:
|
|||||||
int m_exitcode;
|
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
|
// wxEventLoopImpl implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -198,10 +235,13 @@ int wxEventLoop::Run()
|
|||||||
// event loops are not recursive, you need to create another loop!
|
// event loops are not recursive, you need to create another loop!
|
||||||
wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
|
wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
|
||||||
|
|
||||||
m_impl = new wxEventLoopImpl;
|
// SendIdleMessage() and Dispatch() below may throw so the code here should
|
||||||
|
// be exception-safe, hence we must use local objects for all actions we
|
||||||
wxEventLoop *oldLoop = ms_activeLoop;
|
// should undo
|
||||||
ms_activeLoop = this;
|
wxEventLoopActivator activate(&ms_activeLoop, this);
|
||||||
|
wxEventLoopImplTiedPtr impl(&m_impl, new wxEventLoopImpl);
|
||||||
|
|
||||||
|
wxON_BLOCK_EXIT_OBJ0(*this, &wxEventLoop::OnExit);
|
||||||
|
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
@@ -214,8 +254,8 @@ int wxEventLoop::Run()
|
|||||||
while ( !Pending() && m_impl->SendIdleMessage() )
|
while ( !Pending() && m_impl->SendIdleMessage() )
|
||||||
;
|
;
|
||||||
|
|
||||||
// a message came or no more idle processing to do, sit in Dispatch()
|
// a message came or no more idle processing to do, sit in
|
||||||
// waiting for the next message
|
// Dispatch() waiting for the next message
|
||||||
if ( !Dispatch() )
|
if ( !Dispatch() )
|
||||||
{
|
{
|
||||||
// we got WM_QUIT
|
// we got WM_QUIT
|
||||||
@@ -223,13 +263,7 @@ int wxEventLoop::Run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int exitcode = m_impl->GetExitCode();
|
return m_impl->GetExitCode();
|
||||||
delete m_impl;
|
|
||||||
m_impl = NULL;
|
|
||||||
|
|
||||||
ms_activeLoop = oldLoop;
|
|
||||||
|
|
||||||
return exitcode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxEventLoop::Exit(int rc)
|
void wxEventLoop::Exit(int rc)
|
||||||
|
Reference in New Issue
Block a user