]> git.saurik.com Git - wxWidgets.git/commitdiff
fix duplicate events for selection keys after the last change (see #626)
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 6 Mar 2009 16:13:23 +0000 (16:13 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 6 Mar 2009 16:13:23 +0000 (16:13 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59369 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/treectrl.h
src/msw/treectrl.cpp

index 18df088b58521f11196efa39e6f6fbd2343e3ebf..99b1a61a9ebe369448c2e7c3f2cbcbfd218ea2b8 100644 (file)
@@ -244,7 +244,13 @@ protected:
         return !HandleTreeEvent(event) || event.IsAllowed();
     }
 
-    // handle a key event in a multi-selection control
+    // generate a wxEVT_KEY_DOWN event from the specified WPARAM/LPARAM values
+    // having the same meaning as for WM_KEYDOWN, return true if it was
+    // processed
+    bool MSWHandleTreeKeyDownEvent(WXWPARAM wParam, WXLPARAM lParam);
+
+    // handle a key event in a multi-selection control, should be only called
+    // for keys which can be used to change the selection
     //
     // return true if the key was processed, false otherwise
     bool MSWHandleSelectionKey(unsigned vkey);
index 1f45e5b01e49dfede4a8236a5944e1f31b2ff01b..f62d1071790b3429073ef3a542fcc3c62f6377d9 100644 (file)
@@ -2525,6 +2525,40 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey)
     return true;
 }
 
+bool wxTreeCtrl::MSWHandleTreeKeyDownEvent(WXWPARAM wParam, WXLPARAM lParam)
+{
+    wxTreeEvent keyEvent(wxEVT_COMMAND_TREE_KEY_DOWN, this);
+
+    int keyCode = wxCharCodeMSWToWX(wParam);
+
+    if ( !keyCode )
+    {
+        // wxCharCodeMSWToWX() returns 0 to indicate that this is a
+        // simple ASCII key
+        keyCode = wParam;
+    }
+
+    keyEvent.m_evtKey = CreateKeyEvent(wxEVT_KEY_DOWN, keyCode,
+                                       lParam, wParam);
+
+    bool processed = HandleTreeEvent(keyEvent);
+
+    // generate a separate event for Space/Return
+    if ( !wxIsCtrlDown() && !wxIsShiftDown() && !wxIsAltDown() &&
+         ((wParam == VK_SPACE) || (wParam == VK_RETURN)) )
+    {
+        const HTREEITEM htSel = (HTREEITEM)TreeView_GetSelection(GetHwnd());
+        if ( htSel )
+        {
+            wxTreeEvent activatedEvent(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
+                                       this, htSel);
+            (void)HandleTreeEvent(activatedEvent);
+        }
+    }
+
+    return processed;
+}
+
 // we hook into WndProc to process WM_MOUSEMOVE/WM_BUTTONUP messages - as we
 // only do it during dragging, minimize wxWin overhead (this is important for
 // WM_MOUSEMOVE as they're a lot of them) by catching Windows messages directly
@@ -3027,39 +3061,37 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
     }
     else if ( (nMsg == WM_KEYDOWN || nMsg == WM_SYSKEYDOWN) && isMultiple )
     {
-        wxTreeEvent keyEvent(wxEVT_COMMAND_TREE_KEY_DOWN, this);
-
-        int keyCode = wxCharCodeMSWToWX(wParam);
-
-        if ( !keyCode )
+        // normally we want to generate wxEVT_KEY_DOWN events from TVN_KEYDOWN
+        // notification but for the keys which can be used to change selection
+        // we need to do it from here so as to not apply the default behaviour
+        // if the events are handled by the user code
+        switch ( wParam )
         {
-            // wxCharCodeMSWToWX() returns 0 to indicate that this is a
-            // simple ASCII key
-            keyCode = wParam;
-        }
+            case VK_RETURN:
+            case VK_SPACE:
+            case VK_UP:
+            case VK_DOWN:
+            case VK_LEFT:
+            case VK_RIGHT:
+            case VK_HOME:
+            case VK_END:
+            case VK_PRIOR:
+            case VK_NEXT:
+                if ( !MSWHandleTreeKeyDownEvent(wParam, lParam) )
+                {
+                    // use the key to update the selection if it was left
+                    // unprocessed
+                    MSWHandleSelectionKey(wParam);
 
-        keyEvent.m_evtKey = CreateKeyEvent(wxEVT_KEY_DOWN, keyCode,
-                                           lParam, wParam);
+                    // pretend that we did process it in any case as we already
+                    // generated an event for it
+                    processed = true;
+                }
 
-        processed = HandleTreeEvent(keyEvent);
-        if ( !processed )
-        {
-            // update the selection if key was left unprocessed
-            processed = MSWHandleSelectionKey(wParam);
+            //default: for all the other keys leave processed as false so that
+            //         the tree control generates a TVN_KEYDOWN for us
         }
 
-        // generate a separate event for Space/Return
-        if ( !wxIsCtrlDown() && !wxIsShiftDown() && !wxIsAltDown() &&
-             ((wParam == VK_SPACE) || (wParam == VK_RETURN)) )
-        {
-            const HTREEITEM htSel = (HTREEITEM)TreeView_GetSelection(GetHwnd());
-            if ( htSel )
-            {
-                wxTreeEvent activatedEvent(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
-                                           this, htSel);
-                (void)HandleTreeEvent(activatedEvent);
-            }
-        }
     }
     else if ( nMsg == WM_COMMAND )
     {
@@ -3276,43 +3308,8 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 // fabricate the lParam and wParam parameters sufficiently
                 // similar to the ones from a "real" WM_KEYDOWN so that
                 // CreateKeyEvent() works correctly
-                const bool isAltDown = ::GetKeyState(VK_MENU) < 0;
-                WXLPARAM lParam = (isAltDown ? KF_ALTDOWN : 0) << 16;
-
-                WXWPARAM wParam = info->wVKey;
-
-                int keyCode = wxCharCodeMSWToWX(wParam);
-                if ( !keyCode )
-                {
-                    // wxCharCodeMSWToWX() returns 0 to indicate that this is a
-                    // simple ASCII key
-                    keyCode = wParam;
-                }
-
-                wxTreeEvent keyEvent(wxEVT_COMMAND_TREE_KEY_DOWN, this);
-                keyEvent.m_evtKey = CreateKeyEvent(wxEVT_KEY_DOWN,
-                                                keyCode,
-                                                lParam,
-                                                wParam);
-
-                if ( HandleTreeEvent(keyEvent) )
-                {
-                    return true;
-                }
-
-                wxTreeItemId item = wxTreeItemId(TreeView_GetSelection(GetHwnd()));
-
-                // a separate event for Space/Return
-                if ( !wxIsCtrlDown() && !wxIsShiftDown() && !isAltDown &&
-                     ((info->wVKey == VK_SPACE) || (info->wVKey == VK_RETURN)) &&
-                     item )
-                {
-                    wxTreeEvent activatedEvent(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
-                                       this, item);
-                    (void)HandleTreeEvent(activatedEvent);
-                }
-
-                return false;
+                return MSWHandleTreeKeyDownEvent(info->wVKey,
+                                                 wxIsAltDown() << 16);
             }
             break;