]> git.saurik.com Git - wxWidgets.git/commitdiff
Added some more files
authorJulian Smart <julian@anthemion.co.uk>
Fri, 29 Jun 2001 17:21:17 +0000 (17:21 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Fri, 29 Jun 2001 17:21:17 +0000 (17:21 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10726 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/evtloop.h [new file with mode: 0644]
src/generic/fontdlgg.cpp
src/msw/evtloop.cpp [new file with mode: 0644]

diff --git a/include/wx/evtloop.h b/include/wx/evtloop.h
new file mode 100644 (file)
index 0000000..4e90d3d
--- /dev/null
@@ -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 <zeitlin@dptmaths.ens-cachan.fr>
+// 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_
index a7c96f96672a7095513628e31b7afae0b823bc43..90de224fe031c43d18445dc84030df38178a4ec0 100644 (file)
@@ -34,6 +34,8 @@
 #include "wx/intl.h"
 #endif
 
+#if wxUSE_FONTDLG
+
 #include <string.h>
 #include <stdlib.h>
 
@@ -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 (file)
index 0000000..8f45f1e
--- /dev/null
@@ -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 <zeitlin@dptmaths.ens-cachan.fr>
+// 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;
+}
+