]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
adding scroll wheel support
[wxWidgets.git] / src / msw / app.cpp
index 646470fe6fcd21dea007084481d6c9178983f629..342045001abe0e0c4be0d9ec8e2268f72ccbbeab 100644 (file)
 extern void wxSetKeyboardHook(bool doIt);
 #endif
 
-namespace
-{
-
+// because of mingw32 4.3 bug this struct can't be inside the namespace below:
+// see http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/110282
 struct ClassRegInfo
 {
     // the base name of the class: this is used to construct the unique name in
@@ -131,6 +130,9 @@ struct ClassRegInfo
              regnameNR;
 };
 
+namespace
+{
+
 wxVector<ClassRegInfo> gs_regClassesInfo;
 
 } // anonymous namespace
@@ -1013,12 +1015,16 @@ int wxApp::GetShell32Version()
 // Yield to incoming messages
 // ----------------------------------------------------------------------------
 
-bool wxApp::Yield(bool onlyIfNeeded)
-{
-    // MT-FIXME
-    static bool s_inYield = false;
+WX_DECLARE_OBJARRAY(MSG, wxMSGArray);
+
+#include <wx/arrimpl.cpp>
+WX_DEFINE_OBJARRAY(wxMSGArray);
 
-    if ( s_inYield )
+static wxMSGArray g_arrMSG;
+
+bool wxApp::DoYield(bool onlyIfNeeded, long eventsToProcess)
+{
+    if ( m_isInsideYield )
     {
         if ( !onlyIfNeeded )
         {
@@ -1029,9 +1035,10 @@ bool wxApp::Yield(bool onlyIfNeeded)
     }
 
     // set the flag and don't forget to reset it before returning
-    s_inYield = true;
-    wxON_BLOCK_EXIT_SET(s_inYield, false);
+    m_isInsideYield = true;
+    m_eventsToProcessInsideYield = eventsToProcess;
 
+    wxON_BLOCK_EXIT_SET(m_isInsideYield, false);
 
 #if wxUSE_LOG
     // disable log flushing from here because a call to wxYield() shouldn't
@@ -1042,7 +1049,6 @@ bool wxApp::Yield(bool onlyIfNeeded)
     wxON_BLOCK_EXIT0(wxLog::Resume);
 #endif // wxUSE_LOG
 
-
     // we don't want to process WM_QUIT from here - it should be processed in
     // the main event loop in order to stop it
     wxEventLoopGuarantor dummyLoopIfNeeded;
@@ -1054,13 +1060,125 @@ bool wxApp::Yield(bool onlyIfNeeded)
         wxMutexGuiLeaveOrEnter();
 #endif // wxUSE_THREADS
 
-        if ( !wxTheApp->Dispatch() )
+        if (msg.message == WM_PAINT)
+        {
+            // WM_PAINT messages are the last ones of the queue...
             break;
+        }
+
+        // choose a wxEventCategory for this Windows message
+        wxEventCategory cat;
+        switch (msg.message)
+        {
+            case WM_NCMOUSEMOVE:
+            case WM_NCLBUTTONDOWN:
+            case WM_NCLBUTTONUP:
+            case WM_NCLBUTTONDBLCLK:
+            case WM_NCRBUTTONDOWN:
+            case WM_NCRBUTTONUP:
+            case WM_NCRBUTTONDBLCLK:
+            case WM_NCMBUTTONDOWN:
+            case WM_NCMBUTTONUP:
+            case WM_NCMBUTTONDBLCLK:
+
+            case WM_KEYDOWN:
+            case WM_KEYUP:
+            case WM_CHAR:
+            case WM_DEADCHAR:
+            case WM_SYSKEYDOWN:
+            case WM_SYSKEYUP:
+            case WM_SYSCHAR:
+            case WM_SYSDEADCHAR:
+#ifdef WM_UNICHAR
+            case WM_UNICHAR:
+#endif
+            case WM_HOTKEY:
+            case WM_IME_STARTCOMPOSITION:
+            case WM_IME_ENDCOMPOSITION:
+            case WM_IME_COMPOSITION:
+            case WM_COMMAND:
+            case WM_SYSCOMMAND:
+
+            case WM_IME_SETCONTEXT:
+            case WM_IME_NOTIFY:
+            case WM_IME_CONTROL:
+            case WM_IME_COMPOSITIONFULL:
+            case WM_IME_SELECT:
+            case WM_IME_CHAR:
+            case WM_IME_KEYDOWN:
+            case WM_IME_KEYUP:
+
+            case WM_MOUSEHOVER:
+#ifdef WM_NCMOUSELEAVE
+            case WM_NCMOUSELEAVE:
+#endif
+            case WM_MOUSELEAVE:
+
+            case WM_CUT:
+            case WM_COPY:
+            case WM_PASTE:
+            case WM_CLEAR:
+            case WM_UNDO:
+
+            case WM_MOUSEMOVE:
+            case WM_LBUTTONDOWN:
+            case WM_LBUTTONUP:
+            case WM_LBUTTONDBLCLK:
+            case WM_RBUTTONDOWN:
+            case WM_RBUTTONUP:
+            case WM_RBUTTONDBLCLK:
+            case WM_MBUTTONDOWN:
+            case WM_MBUTTONUP:
+            case WM_MBUTTONDBLCLK:
+            case WM_MOUSEWHEEL:
+                cat = wxEVT_CATEGORY_USER_INPUT;
+                break;
+
+            case WM_TIMER:
+                cat = wxEVT_CATEGORY_TIMER;
+                break;
+
+            default:
+                if (msg.message < WM_USER)
+                {
+                    // 0;WM_USER-1 is the range of message IDs reserved for use
+                    // by the system.
+
+                    // there are too many of these types of messages to handle
+                    // them in this switch
+                    cat = wxEVT_CATEGORY_UI;
+                }
+                else
+                    cat = wxEVT_CATEGORY_UNKNOWN;
+        }
+
+        // should we process this event now?
+        if (cat & eventsToProcess)
+        {
+            if ( !wxTheApp->Dispatch() )
+                break;
+        }
+        else
+        {
+            // remove the message and store it
+            ::GetMessage(&msg, NULL, 0, 0);
+            g_arrMSG.Add(msg);
+        }
     }
 
     // if there are pending events, we must process them.
     ProcessPendingEvents();
 
+    // put back unprocessed events in the queue
+    DWORD id = GetCurrentThreadId();
+    for (size_t i=0; i<g_arrMSG.GetCount(); i++)
+    {
+        PostThreadMessage(id, g_arrMSG[i].message,
+                          g_arrMSG[i].wParam, g_arrMSG[i].lParam);
+    }
+
+    g_arrMSG.Clear();
+
     return true;
 }