]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/treectrl.cpp
Some change logs
[wxWidgets.git] / src / msw / treectrl.cpp
index 93bdeea6e795f5b87b8fc65b92806da6432fe71d..2df7fb4f75b6677a6d13abea9bcf6b2a99d25137 100644 (file)
 
 #include "wx/msw/private.h"
 
 
 #include "wx/msw/private.h"
 
+// include <commctrl.h> "properly"
+#include "wx/msw/wrapcctl.h"
+
+#include "wx/msw/missing.h"
+
 // Set this to 1 to be _absolutely_ sure that repainting will work for all
 // comctl32.dll versions
 #define wxUSE_COMCTL32_SAFELY 0
 // Set this to 1 to be _absolutely_ sure that repainting will work for all
 // comctl32.dll versions
 #define wxUSE_COMCTL32_SAFELY 0
@@ -44,9 +49,6 @@
 #include "wx/msw/treectrl.h"
 #include "wx/msw/dragimag.h"
 
 #include "wx/msw/treectrl.h"
 #include "wx/msw/dragimag.h"
 
-// include <commctrl.h> "properly"
-#include "wx/msw/wrapcctl.h"
-
 // macros to hide the cast ugliness
 // --------------------------------
 
 // macros to hide the cast ugliness
 // --------------------------------
 
@@ -346,7 +348,8 @@ public:
         {
             m_selections.Empty();
 
         {
             m_selections.Empty();
 
-            DoTraverse(tree->GetRootItem());
+            if (tree->GetCount() > 0)
+                DoTraverse(tree->GetRootItem());
         }
 
     virtual bool OnVisit(const wxTreeItemId& item)
         }
 
     virtual bool OnVisit(const wxTreeItemId& item)
@@ -677,7 +680,7 @@ bool wxTreeCtrl::Create(wxWindow *parent,
         wstyle |= TVS_CHECKBOXES;
 #endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
 
         wstyle |= TVS_CHECKBOXES;
 #endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
 
-#ifndef __WXWINCE__
+#if !defined(__WXWINCE__) && defined(TVS_INFOTIP)
     // Need so that TVN_GETINFOTIP messages will be sent
     wstyle |= TVS_INFOTIP;
 #endif
     // Need so that TVN_GETINFOTIP messages will be sent
     wstyle |= TVS_INFOTIP;
 #endif
@@ -2243,20 +2246,42 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
     WXLRESULT rc = 0;
     bool isMultiple = HasFlag(wxTR_MULTIPLE);
 
     WXLRESULT rc = 0;
     bool isMultiple = HasFlag(wxTR_MULTIPLE);
 
-#ifdef WM_CONTEXTMENU
+    // This message is sent after a right-click, or when the "menu" key is pressed
     if ( nMsg == WM_CONTEXTMENU )
     {
     if ( nMsg == WM_CONTEXTMENU )
     {
+        int x = GET_X_LPARAM(lParam),
+            y = GET_Y_LPARAM(lParam);
+        // Convert the screen point to a client point
+        wxPoint MenuPoint = ScreenToClient(wxPoint(x, y));
+
         wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_MENU, GetId() );
 
         // can't use GetSelection() here as it would assert in multiselect mode
         event.m_item = wxTreeItemId(TreeView_GetSelection(GetHwnd()));
         event.SetEventObject( this );
 
         wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_MENU, GetId() );
 
         // can't use GetSelection() here as it would assert in multiselect mode
         event.m_item = wxTreeItemId(TreeView_GetSelection(GetHwnd()));
         event.SetEventObject( this );
 
+        // Get the bounding rectangle for the item, including the non-text areas
+        wxRect ItemRect;
+        GetBoundingRect(event.m_item, ItemRect, false);
+        // If the point is inside the bounding rectangle, use it as the click position.
+        // This should be the case for WM_CONTEXTMENU as the result of a right-click
+        if (ItemRect.Inside(MenuPoint))
+        {
+            event.m_pointDrag = MenuPoint;
+        }
+        // Use the Explorer standard of putting the menu at the left edge of the text,
+        // in the vertical middle of the text. Should be the case for the "menu" key
+        else
+        {
+            // Use the bounding rectangle of only the text part
+            GetBoundingRect(event.m_item, ItemRect, true);
+            event.m_pointDrag = wxPoint(ItemRect.GetX(), ItemRect.GetY() + ItemRect.GetHeight() / 2);
+        }
+
         if ( GetEventHandler()->ProcessEvent(event) )
             processed = true;
         //else: continue with generating wxEVT_CONTEXT_MENU in base class code
     }
         if ( GetEventHandler()->ProcessEvent(event) )
             processed = true;
         //else: continue with generating wxEVT_CONTEXT_MENU in base class code
     }
-#endif // WM_CONTEXTMENU
     else if ( (nMsg >= WM_MOUSEFIRST) && (nMsg <= WM_MOUSELAST) )
     {
         // we only process mouse messages here and these parameters have the
     else if ( (nMsg >= WM_MOUSEFIRST) && (nMsg <= WM_MOUSELAST) )
     {
         // we only process mouse messages here and these parameters have the
@@ -2517,18 +2542,6 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
         }
     }
 #endif // !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
         }
     }
 #endif // !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-    else if ( nMsg == WM_CHAR )
-    {
-        // don't let the control process Space and Return keys because it
-        // doesn't do anything useful with them anyhow but always beeps
-        // annoyingly when it receives them and there is no way to turn it off
-        // simply if you just process TREEITEM_ACTIVATED event to which Space
-        // and Enter presses are mapped in your code
-        if ( wParam == VK_SPACE || wParam == VK_RETURN )
-        {
-            processed = true;
-        }
-    }
     else if ( nMsg == WM_COMMAND )
     {
         // if we receive a EN_KILLFOCUS command from the in-place edit control
     else if ( nMsg == WM_COMMAND )
     {
         // if we receive a EN_KILLFOCUS command from the in-place edit control
@@ -2564,6 +2577,33 @@ wxTreeCtrl::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
     if ( nMsg == WM_RBUTTONDOWN )
         return 0;
 
     if ( nMsg == WM_RBUTTONDOWN )
         return 0;
 
+    // but because of the above we don't get NM_RCLICK which is normally
+    // generated by tree window proc when the modal loop mentioned above ends
+    // because the mouse is released -- synthesize it ourselves instead
+    if ( nMsg == WM_RBUTTONUP )
+    {
+        NMHDR hdr;
+        hdr.hwndFrom = GetHwnd();
+        hdr.idFrom = GetId();
+        hdr.code = NM_RCLICK;
+
+        WXLPARAM rc;
+        MSWOnNotify(GetId(), (LPARAM)&hdr, &rc);
+
+        // continue as usual
+    }
+
+    if ( nMsg == WM_CHAR )
+    {
+        // also don't let the control process Space and Return keys because it
+        // doesn't do anything useful with them anyhow but always beeps
+        // annoyingly when it receives them and there is no way to turn it off
+        // simply if you just process TREEITEM_ACTIVATED event to which Space
+        // and Enter presses are mapped in your code
+        if ( wParam == VK_SPACE || wParam == VK_RETURN )
+            return 0;
+    }
+
     return wxControl::MSWDefWindowProc(nMsg, wParam, lParam);
 }
 
     return wxControl::MSWDefWindowProc(nMsg, wParam, lParam);
 }
 
@@ -2655,6 +2695,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 break;
             }
 
                 break;
             }
 
+#ifdef TVN_GETINFOTIP
         case TVN_GETINFOTIP:
             {
                 eventType = wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP;
         case TVN_GETINFOTIP:
             {
                 eventType = wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP;
@@ -2665,6 +2706,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
                 break;
             }
 
                 break;
             }
+#endif
 #endif
 
         case TVN_GETDISPINFO:
 #endif
 
         case TVN_GETDISPINFO:
@@ -3019,6 +3061,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
             break;
 
 #ifndef __WXWINCE__
             break;
 
 #ifndef __WXWINCE__
+#ifdef TVN_GETINFOTIP
          case TVN_GETINFOTIP:
             {
                 // If the user permitted a tooltip change, change it
          case TVN_GETINFOTIP:
             {
                 // If the user permitted a tooltip change, change it
@@ -3028,6 +3071,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 }
             }
             break;
                 }
             }
             break;
+#endif
 #endif
 
         case TVN_SELCHANGING:
 #endif
 
         case TVN_SELCHANGING: