use wxEventLoop in wxApp under wxMSW; factored out common code from wxX11/wxMotif/wxMGL to wxAppBase; changed wxApp::Dispatch() return type
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23609 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -32,6 +32,8 @@ class WXDLLIMPEXP_BASE wxCmdLineParser;
|
|||||||
class WXDLLIMPEXP_BASE wxLog;
|
class WXDLLIMPEXP_BASE wxLog;
|
||||||
class WXDLLIMPEXP_BASE wxMessageOutput;
|
class WXDLLIMPEXP_BASE wxMessageOutput;
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxEventLoop;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// typedefs
|
// typedefs
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -367,24 +369,27 @@ public:
|
|||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
// execute the main GUI loop, the function returns when the loop ends
|
// 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
|
// exit the main loop thus terminating the application
|
||||||
virtual void Exit();
|
virtual void Exit();
|
||||||
|
|
||||||
// exit the main GUI loop during the next iteration (i.e. it does not
|
// exit the main GUI loop during the next iteration (i.e. it does not
|
||||||
// stop the program immediately!)
|
// 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;
|
virtual bool Initialized() = 0;
|
||||||
|
|
||||||
// returns TRUE if there are unprocessed events in the event queue
|
// 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
|
// process the first event in the event queue (blocks until an event
|
||||||
// apperas if there are none currently)
|
// appears if there are none currently, use Pending() if this is not
|
||||||
virtual void Dispatch() = 0;
|
// wanted), returns false if the event loop should stop and true
|
||||||
|
// otherwise
|
||||||
|
virtual bool Dispatch();
|
||||||
|
|
||||||
// process all currently pending events right now
|
// process all currently pending events right now
|
||||||
//
|
//
|
||||||
@@ -402,7 +407,7 @@ public:
|
|||||||
// parties
|
// parties
|
||||||
//
|
//
|
||||||
// it should return TRUE if more idle events are needed, FALSE if not
|
// 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
|
// Send idle event to window and all subwindows
|
||||||
// Returns TRUE if more idle time is requested.
|
// Returns TRUE if more idle time is requested.
|
||||||
@@ -493,6 +498,10 @@ protected:
|
|||||||
virtual wxAppTraits *CreateTraits();
|
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)
|
// the main top level window (may be NULL)
|
||||||
wxWindow *m_topWindow;
|
wxWindow *m_topWindow;
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ public:
|
|||||||
virtual void ExitMainLoop();
|
virtual void ExitMainLoop();
|
||||||
virtual bool Initialized();
|
virtual bool Initialized();
|
||||||
virtual bool Pending();
|
virtual bool Pending();
|
||||||
virtual void Dispatch();
|
virtual bool Dispatch();
|
||||||
|
|
||||||
virtual void Exit();
|
virtual void Exit();
|
||||||
|
|
||||||
|
@@ -45,7 +45,7 @@ public:
|
|||||||
virtual void ExitMainLoop();
|
virtual void ExitMainLoop();
|
||||||
virtual bool Initialized();
|
virtual bool Initialized();
|
||||||
virtual bool Pending();
|
virtual bool Pending();
|
||||||
virtual void Dispatch();
|
virtual bool Dispatch();
|
||||||
|
|
||||||
virtual void Exit();
|
virtual void Exit();
|
||||||
|
|
||||||
|
@@ -45,7 +45,7 @@ public:
|
|||||||
virtual void ExitMainLoop();
|
virtual void ExitMainLoop();
|
||||||
virtual bool Initialized();
|
virtual bool Initialized();
|
||||||
virtual bool Pending();
|
virtual bool Pending();
|
||||||
virtual void Dispatch();
|
virtual bool Dispatch();
|
||||||
|
|
||||||
virtual void Exit();
|
virtual void Exit();
|
||||||
|
|
||||||
|
@@ -51,7 +51,7 @@ class WXDLLEXPORT wxApp: public wxAppBase
|
|||||||
virtual void ExitMainLoop();
|
virtual void ExitMainLoop();
|
||||||
virtual bool Initialized();
|
virtual bool Initialized();
|
||||||
virtual bool Pending() ;
|
virtual bool Pending() ;
|
||||||
virtual void Dispatch() ;
|
virtual bool Dispatch() ;
|
||||||
|
|
||||||
virtual void Exit();
|
virtual void Exit();
|
||||||
|
|
||||||
|
@@ -42,11 +42,7 @@ public:
|
|||||||
virtual bool OnInitGui();
|
virtual bool OnInitGui();
|
||||||
|
|
||||||
// override base class (pure) virtuals
|
// override base class (pure) virtuals
|
||||||
virtual int MainLoop();
|
|
||||||
virtual void ExitMainLoop();
|
|
||||||
virtual bool Initialized();
|
virtual bool Initialized();
|
||||||
virtual bool Pending();
|
|
||||||
virtual void Dispatch();
|
|
||||||
|
|
||||||
virtual bool Initialize(int& argc, wxChar **argv);
|
virtual bool Initialize(int& argc, wxChar **argv);
|
||||||
virtual void CleanUp();
|
virtual void CleanUp();
|
||||||
@@ -60,7 +56,6 @@ private:
|
|||||||
DECLARE_DYNAMIC_CLASS(wxApp)
|
DECLARE_DYNAMIC_CLASS(wxApp)
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
wxEventLoop *m_mainLoop;
|
|
||||||
wxDisplayModeInfo m_displayMode;
|
wxDisplayModeInfo m_displayMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -53,8 +53,6 @@ public:
|
|||||||
virtual int MainLoop();
|
virtual int MainLoop();
|
||||||
virtual void ExitMainLoop();
|
virtual void ExitMainLoop();
|
||||||
virtual bool Initialized();
|
virtual bool Initialized();
|
||||||
virtual bool Pending();
|
|
||||||
virtual void Dispatch();
|
|
||||||
|
|
||||||
virtual void Exit();
|
virtual void Exit();
|
||||||
|
|
||||||
|
@@ -39,11 +39,7 @@ public:
|
|||||||
virtual bool Initialize(int& argc, wxChar **argv);
|
virtual bool Initialize(int& argc, wxChar **argv);
|
||||||
virtual void CleanUp();
|
virtual void CleanUp();
|
||||||
|
|
||||||
virtual int MainLoop();
|
|
||||||
virtual void ExitMainLoop();
|
|
||||||
virtual bool Initialized();
|
virtual bool Initialized();
|
||||||
virtual bool Pending();
|
|
||||||
virtual void Dispatch();
|
|
||||||
|
|
||||||
virtual bool Yield(bool onlyIfNeeded = FALSE);
|
virtual bool Yield(bool onlyIfNeeded = FALSE);
|
||||||
virtual void WakeUpIdle();
|
virtual void WakeUpIdle();
|
||||||
@@ -67,18 +63,6 @@ public:
|
|||||||
static bool RegisterWindowClasses();
|
static bool RegisterWindowClasses();
|
||||||
static bool UnregisterWindowClasses();
|
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
|
// idle processing
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
||||||
@@ -98,9 +82,6 @@ public:
|
|||||||
static int m_nCmdShow;
|
static int m_nCmdShow;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// we exit the main event loop when this flag becomes false
|
|
||||||
bool m_keepGoing;
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_NO_COPY_CLASS(wxApp)
|
DECLARE_NO_COPY_CLASS(wxApp)
|
||||||
};
|
};
|
||||||
|
@@ -75,7 +75,7 @@ public:
|
|||||||
virtual void ExitMainLoop(void);
|
virtual void ExitMainLoop(void);
|
||||||
virtual bool Initialized(void);
|
virtual bool Initialized(void);
|
||||||
virtual bool Pending(void) ;
|
virtual bool Pending(void) ;
|
||||||
virtual void Dispatch(void);
|
virtual bool Dispatch(void);
|
||||||
|
|
||||||
virtual void Exit();
|
virtual void Exit();
|
||||||
|
|
||||||
|
@@ -32,7 +32,6 @@ class WXDLLEXPORT wxWindow;
|
|||||||
class WXDLLEXPORT wxApp;
|
class WXDLLEXPORT wxApp;
|
||||||
class WXDLLEXPORT wxKeyEvent;
|
class WXDLLEXPORT wxKeyEvent;
|
||||||
class WXDLLEXPORT wxLog;
|
class WXDLLEXPORT wxLog;
|
||||||
class WXDLLEXPORT wxEventLoop;
|
|
||||||
class WXDLLEXPORT wxXVisualInfo;
|
class WXDLLEXPORT wxXVisualInfo;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -126,7 +125,6 @@ protected:
|
|||||||
WXWindow m_topLevelWidget;
|
WXWindow m_topLevelWidget;
|
||||||
WXColormap m_mainColormap;
|
WXColormap m_mainColormap;
|
||||||
long m_maxRequestSize;
|
long m_maxRequestSize;
|
||||||
wxEventLoop* m_mainLoop;
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
@@ -273,8 +273,9 @@ bool wxApp::Pending()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch a message.
|
// Dispatch a message.
|
||||||
void wxApp::Dispatch()
|
bool wxApp::Dispatch()
|
||||||
{
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Yield to other processes
|
// Yield to other processes
|
||||||
|
@@ -41,9 +41,11 @@
|
|||||||
|
|
||||||
#include "wx/apptrait.h"
|
#include "wx/apptrait.h"
|
||||||
#include "wx/cmdline.h"
|
#include "wx/cmdline.h"
|
||||||
|
#include "wx/evtloop.h"
|
||||||
#include "wx/msgout.h"
|
#include "wx/msgout.h"
|
||||||
#include "wx/thread.h"
|
#include "wx/thread.h"
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
|
#include "wx/ptr_scpd.h"
|
||||||
|
|
||||||
#if defined(__WXMSW__)
|
#if defined(__WXMSW__)
|
||||||
#include "wx/msw/private.h" // includes windows.h for LOGFONT
|
#include "wx/msw/private.h" // includes windows.h for LOGFONT
|
||||||
@@ -57,6 +59,30 @@
|
|||||||
#include "wx/build.h"
|
#include "wx/build.h"
|
||||||
WX_CHECK_BUILD_OPTIONS("wxCore")
|
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
|
// wxAppBase implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -71,6 +97,8 @@ wxAppBase::wxAppBase()
|
|||||||
m_useBestVisual = FALSE;
|
m_useBestVisual = FALSE;
|
||||||
m_isActive = TRUE;
|
m_isActive = TRUE;
|
||||||
|
|
||||||
|
m_mainLoop = NULL;
|
||||||
|
|
||||||
// We don't want to exit the app if the user code shows a dialog from its
|
// 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
|
// 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.
|
// 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
|
#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
|
// OnXXX() hooks
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -567,9 +567,11 @@ bool wxApp::Pending()
|
|||||||
return (gtk_events_pending() > 0);
|
return (gtk_events_pending() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxApp::Dispatch()
|
bool wxApp::Dispatch()
|
||||||
{
|
{
|
||||||
gtk_main_iteration();
|
gtk_main_iteration();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxApp::Initialize(int& argc, wxChar **argv)
|
bool wxApp::Initialize(int& argc, wxChar **argv)
|
||||||
|
@@ -567,9 +567,11 @@ bool wxApp::Pending()
|
|||||||
return (gtk_events_pending() > 0);
|
return (gtk_events_pending() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxApp::Dispatch()
|
bool wxApp::Dispatch()
|
||||||
{
|
{
|
||||||
gtk_main_iteration();
|
gtk_main_iteration();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxApp::Initialize(int& argc, wxChar **argv)
|
bool wxApp::Initialize(int& argc, wxChar **argv)
|
||||||
|
@@ -1049,9 +1049,11 @@ bool wxApp::Pending()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch a message.
|
// Dispatch a message.
|
||||||
void wxApp::Dispatch()
|
bool wxApp::Dispatch()
|
||||||
{
|
{
|
||||||
MacDoOneEvent() ;
|
MacDoOneEvent() ;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxApp::OnIdle(wxIdleEvent& event)
|
void wxApp::OnIdle(wxIdleEvent& event)
|
||||||
|
@@ -1049,9 +1049,11 @@ bool wxApp::Pending()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch a message.
|
// Dispatch a message.
|
||||||
void wxApp::Dispatch()
|
bool wxApp::Dispatch()
|
||||||
{
|
{
|
||||||
MacDoOneEvent() ;
|
MacDoOneEvent() ;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxApp::OnIdle(wxIdleEvent& event)
|
void wxApp::OnIdle(wxIdleEvent& event)
|
||||||
|
@@ -272,37 +272,9 @@ bool wxApp::OnInitGui()
|
|||||||
return TRUE;
|
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()
|
bool wxApp::Initialized()
|
||||||
{
|
{
|
||||||
return (wxTopLevelWindows.GetCount() != 0);
|
return wxTopLevelWindows.GetCount() != 0;
|
||||||
}
|
|
||||||
|
|
||||||
bool wxApp::Pending()
|
|
||||||
{
|
|
||||||
return wxEventLoop::GetActive()->Pending();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxApp::Dispatch()
|
|
||||||
{
|
|
||||||
wxEventLoop::GetActive()->Dispatch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxApp::Initialize(int& argc, wxChar **argv)
|
bool wxApp::Initialize(int& argc, wxChar **argv)
|
||||||
|
@@ -176,25 +176,6 @@ void wxApp::ExitMainLoop()
|
|||||||
m_eventLoop->Exit();
|
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
|
// This should be redefined in a derived class for
|
||||||
// handling property change events for XAtom IPC.
|
// handling property change events for XAtom IPC.
|
||||||
void wxApp::HandlePropertyChange(WXEvent *event)
|
void wxApp::HandlePropertyChange(WXEvent *event)
|
||||||
|
221
src/msw/app.cpp
221
src/msw/app.cpp
@@ -103,8 +103,6 @@ extern wxList WXDLLEXPORT wxPendingDelete;
|
|||||||
extern void wxSetKeyboardHook(bool doIt);
|
extern void wxSetKeyboardHook(bool doIt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MSG s_currentMsg;
|
|
||||||
|
|
||||||
// NB: all "NoRedraw" classes must have the same names as the "normal" classes
|
// NB: all "NoRedraw" classes must have the same names as the "normal" classes
|
||||||
// with NR suffix - wxWindow::MSWCreate() supposes this
|
// with NR suffix - wxWindow::MSWCreate() supposes this
|
||||||
const wxChar *wxCanvasClassName = wxT("wxWindowClass");
|
const wxChar *wxCanvasClassName = wxT("wxWindowClass");
|
||||||
@@ -200,7 +198,9 @@ void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
|
|||||||
|
|
||||||
bool wxGUIAppTraits::DoMessageFromThreadWait()
|
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()
|
wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo()
|
||||||
@@ -568,219 +568,6 @@ bool wxApp::Initialized()
|
|||||||
#endif
|
#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
|
// this is a temporary hack and will be replaced by using wxEventLoop in the
|
||||||
// future
|
// future
|
||||||
//
|
//
|
||||||
@@ -965,7 +752,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
|||||||
wxMutexGuiLeaveOrEnter();
|
wxMutexGuiLeaveOrEnter();
|
||||||
#endif // wxUSE_THREADS
|
#endif // wxUSE_THREADS
|
||||||
|
|
||||||
if ( !wxTheApp->DoMessage() )
|
if ( !wxTheApp->Dispatch() )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -162,9 +162,6 @@
|
|||||||
// global variables
|
// global variables
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// the last Windows message we got (FIXME-MT)
|
|
||||||
extern MSG s_currentMsg;
|
|
||||||
|
|
||||||
#if wxUSE_MENUS_NATIVE
|
#if wxUSE_MENUS_NATIVE
|
||||||
wxMenu *wxCurrentPopupMenu = NULL;
|
wxMenu *wxCurrentPopupMenu = NULL;
|
||||||
#endif // wxUSE_MENUS_NATIVE
|
#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
|
// peek all WM_COMMANDs (it will always return WM_QUIT too but we don't
|
||||||
// want to process it here)
|
// want to process it here)
|
||||||
MSG msg;
|
MSG msg;
|
||||||
while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE)
|
while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE) )
|
||||||
&& msg.message != WM_QUIT )
|
|
||||||
{
|
{
|
||||||
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.
|
// luckily (as we don't have access to wxEventLoopImpl method from here
|
||||||
if (msg.message == WM_QUIT)
|
// anyhow...) we don't need to pre process WM_COMMANDs so dispatch it
|
||||||
::PostQuitMessage(0);
|
// immediately
|
||||||
|
::TranslateMessage(&msg);
|
||||||
|
::DispatchMessage(&msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
|
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||||
@@ -4220,7 +4223,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
|
|||||||
// so simply test for negative value.
|
// so simply test for negative value.
|
||||||
event.m_altDown = ::GetKeyState(VK_MENU) < 0;
|
event.m_altDown = ::GetKeyState(VK_MENU) < 0;
|
||||||
|
|
||||||
event.SetTimestamp(s_currentMsg.time);
|
event.SetTimestamp(::GetMessageTime());
|
||||||
event.m_eventObject = this;
|
event.m_eventObject = this;
|
||||||
event.SetId(GetId());
|
event.SetId(GetId());
|
||||||
|
|
||||||
@@ -4418,7 +4421,7 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
|
|||||||
event.m_keyCode = id;
|
event.m_keyCode = id;
|
||||||
event.m_rawCode = (wxUint32) wParam;
|
event.m_rawCode = (wxUint32) wParam;
|
||||||
event.m_rawFlags = (wxUint32) lParam;
|
event.m_rawFlags = (wxUint32) lParam;
|
||||||
event.SetTimestamp(s_currentMsg.time);
|
event.SetTimestamp(::GetMessageTime());
|
||||||
|
|
||||||
// translate the position to client coords
|
// translate the position to client coords
|
||||||
POINT pt;
|
POINT pt;
|
||||||
@@ -5092,7 +5095,7 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
|
|||||||
event.m_keyCode = id;
|
event.m_keyCode = id;
|
||||||
event.m_shiftDown = wxIsShiftDown();
|
event.m_shiftDown = wxIsShiftDown();
|
||||||
event.m_controlDown = wxIsCtrlDown();
|
event.m_controlDown = wxIsCtrlDown();
|
||||||
event.SetTimestamp(s_currentMsg.time);
|
event.SetTimestamp(::GetMessageTime());
|
||||||
|
|
||||||
wxWindow *win = wxGetActiveWindow();
|
wxWindow *win = wxGetActiveWindow();
|
||||||
wxEvtHandler *handler;
|
wxEvtHandler *handler;
|
||||||
|
Reference in New Issue
Block a user