From 3808e191421b1337b3c688cf6d75efa43582547a Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Fri, 29 Jun 2001 17:21:17 +0000 Subject: [PATCH] Added some more files git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10726 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/evtloop.h | 52 ++++++++ src/generic/fontdlgg.cpp | 4 + src/msw/evtloop.cpp | 278 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 334 insertions(+) create mode 100644 include/wx/evtloop.h create mode 100644 src/msw/evtloop.cpp diff --git a/include/wx/evtloop.h b/include/wx/evtloop.h new file mode 100644 index 0000000000..4e90d3d803 --- /dev/null +++ b/include/wx/evtloop.h @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/evtloop.h +// Purpose: declares wxEventLoop class +// Author: Vadim Zeitlin +// Modified by: +// Created: 01.06.01 +// RCS-ID: $Id$ +// Copyright: (c) 2001 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_EVTLOOP_H_ +#define _WX_EVTLOOP_H_ + +#ifdef __GNUG__ + #pragma interface "evtloop.h" +#endif + +// ---------------------------------------------------------------------------- +// wxEventLoop: a GUI event loop +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxEventLoop +{ +public: + // ctor + wxEventLoop() { m_impl = NULL; } + + // dtor + virtual ~wxEventLoop(); + + // start the event loop, return the exit code when it is finished + virtual int Run(); + + // exit from the loop with the given exit code + virtual void Exit(int rc = 0); + + // return TRUE if any events are available + virtual bool Pending() const; + + // dispatch a single event, return FALSE if we should exit from the loop + virtual bool Dispatch(); + + // is the event loop running now? + virtual bool IsRunning() const; + +protected: + // the pointer to the port specific implementation class + class WXDLLEXPORT wxEventLoopImpl *m_impl; +}; + +#endif // _WX_EVTLOOP_H_ diff --git a/src/generic/fontdlgg.cpp b/src/generic/fontdlgg.cpp index a7c96f9667..90de224fe0 100644 --- a/src/generic/fontdlgg.cpp +++ b/src/generic/fontdlgg.cpp @@ -34,6 +34,8 @@ #include "wx/intl.h" #endif +#if wxUSE_FONTDLG + #include #include @@ -447,4 +449,6 @@ int wxFontWeightStringToInt(wxChar *weight) return wxNORMAL; } +#endif + // wxUSE_FONTDLG diff --git a/src/msw/evtloop.cpp b/src/msw/evtloop.cpp new file mode 100644 index 0000000000..8f45f1e05f --- /dev/null +++ b/src/msw/evtloop.cpp @@ -0,0 +1,278 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: msw/evtloop.cpp +// Purpose: implements wxEventLoop for MSW +// Author: Vadim Zeitlin +// Modified by: +// Created: 01.06.01 +// RCS-ID: $Id$ +// Copyright: (c) 2001 Vadim Zeitlin +// License: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "evtloop.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#endif //WX_PRECOMP + +#include "wx/evtloop.h" + +#include "wx/msw/private.h" + +// ---------------------------------------------------------------------------- +// wxEventLoopImpl +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxEventLoopImpl +{ +public: + // ctor + wxEventLoopImpl() { SetExitCode(0); } + + // process a message + void ProcessMessage(MSG *msg); + + // generate an idle message, return TRUE if more idle time requested + bool SendIdleMessage(); + + // set/get the exit code + void SetExitCode(int exitcode) { m_exitcode = exitcode; } + int GetExitCode() const { return m_exitcode; } + +private: + // preprocess a message, return TRUE if processed (i.e. no further + // dispatching required) + bool PreProcessMessage(MSG *msg); + + // the exit code of the event loop + int m_exitcode; +}; + +// ============================================================================ +// wxEventLoopImpl implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxEventLoopImpl message processing +// ---------------------------------------------------------------------------- + +void wxEventLoopImpl::ProcessMessage(MSG *msg) +{ + // give us the chance to preprocess the message first + if ( !PreProcessMessage(msg) ) + { + // if it wasn't done, dispatch it to the corresponding window + ::TranslateMessage(msg); + ::DispatchMessage(msg); + } +} + +bool wxEventLoopImpl::PreProcessMessage(MSG *msg) +{ + HWND hWnd = msg->hwnd; + wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hWnd); + +#if wxUSE_TOOLTIPS + // we must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to + // popup the tooltip bubbles + if ( wndThis && (msg->message == WM_MOUSEMOVE) ) + { + wxToolTip *tt = wndThis->GetToolTip(); + if ( tt ) + { + tt->RelayEvent((WXMSG *)msg); + } + } +#endif // wxUSE_TOOLTIPS + + // try translations first; find the youngest window with a translation + // table. + wxWindow *wnd; + for ( wnd = wndThis; wnd; wnd = wnd->GetParent() ) + { + if ( wnd->MSWTranslateMessage((WXMSG *)msg) ) + return TRUE; + } + + // Anyone for a non-translation message? Try youngest descendants first. + for ( wnd = wndThis; wnd; wnd = wnd->GetParent() ) + { + if ( wnd->MSWProcessMessage((WXMSG *)msg) ) + return TRUE; + } + + return FALSE; +} + +// ---------------------------------------------------------------------------- +// wxEventLoopImpl idle event processing +// ---------------------------------------------------------------------------- + +bool wxEventLoopImpl::SendIdleMessage() +{ + wxIdleEvent event; + + return wxTheApp->ProcessEvent(event) && event.MoreRequested(); +} + +// ============================================================================ +// wxEventLoop implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxEventLoop running and exiting +// ---------------------------------------------------------------------------- + +wxEventLoop::~wxEventLoop() +{ + wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") ); +} + +bool wxEventLoop::IsRunning() const +{ + return m_impl != NULL; +} + +int wxEventLoop::Run() +{ + // 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; + + 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() && m_impl->SendIdleMessage() ) + ; + + // 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; + } + } + + int exitcode = m_impl->GetExitCode(); + delete m_impl; + m_impl = NULL; + + return exitcode; +} + +void wxEventLoop::Exit(int rc) +{ + wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") ); + + m_impl->SetExitCode(rc); + + ::PostQuitMessage(rc); +} + +// ---------------------------------------------------------------------------- +// wxEventLoop message processing dispatching +// ---------------------------------------------------------------------------- + +bool wxEventLoop::Pending() const +{ + MSG msg; + return ::PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE) != 0; +} + +bool wxEventLoop::Dispatch() +{ + wxCHECK_MSG( IsRunning(), FALSE, _T("can't call Dispatch() if not running") ); + + MSG msg; + BOOL rc = ::GetMessage(&msg, (HWND) NULL, 0, 0); + + if ( rc == 0 ) + { + // got WM_QUIT + return FALSE; + } + + if ( rc == -1 ) + { + // should never happen, but let's test for it nevertheless + wxLogLastError(wxT("GetMessage")); + + // still break from the loop + return FALSE; + } + +#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 owning the mutex 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.Count(); + for ( size_t n = 0; n < count; n++ ) + { + MSG& msg = s_aSavedMessages[n]; + m_impl->ProcessMessage(&msg); + } + + s_aSavedMessages.Empty(); + } + } +#endif // wxUSE_THREADS + + m_impl->ProcessMessage(&msg); + + return TRUE; +} + -- 2.45.2