]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/treectrl.cpp
added $Id$ to the header
[wxWidgets.git] / src / msw / treectrl.cpp
index cafa1850313dc93248e17ac78f745c872bdd4e05..92dc2fce7d58ffbe704492331d45b9f3593d22f0 100644 (file)
@@ -29,6 +29,8 @@
 #include "wx/treectrl.h"
 
 #ifndef WX_PRECOMP
+    #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
+    #include "wx/msw/missing.h"
     #include "wx/dynarray.h"
     #include "wx/log.h"
     #include "wx/app.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
 // get HTREEITEM from wxTreeItemId
 #define HITEM(item)     ((HTREEITEM)(((item).m_pItem)))
 
-// the native control doesn't support multiple selections under MSW and we
-// have 2 ways to emulate them: either using TVS_CHECKBOXES style and let
-// checkboxes be the selection status (checked == selected) or by really
-// emulating everything, i.e. intercepting mouse and key events &c. The first
-// approach is much easier but doesn't work with comctl32.dll < 4.71 and also
-// looks quite ugly.
-#define wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE 0
-
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
@@ -77,8 +66,6 @@ static HTREEITEM GetItemFromPoint(HWND hwndTV, int x, int y)
     return (HTREEITEM)TreeView_HitTest(hwndTV, &tvht);
 }
 
-#if !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-
 // wrappers for TreeView_GetItem/TreeView_SetItem
 static bool IsItemSelected(HWND hwndTV, HTREEITEM hItem)
 {
@@ -244,8 +231,6 @@ static void SetFocus(HWND hwndTV, HTREEITEM htItem)
     }
 }
 
-#endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-
 // ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
@@ -459,11 +444,7 @@ public:
             return true;
         }
 
-#if wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-        if ( tree->IsItemChecked(item) )
-#else
         if ( ::IsItemSelected(GetHwndOf(tree), HITEM(item)) )
-#endif
         {
             m_selections.Add(item);
         }
@@ -678,7 +659,7 @@ bool wxTreeCtrl::Create(wxWindow *parent,
     if ( !CreateControl(parent, id, pos, size, style, validator, name) )
         return false;
 
-    DWORD exStyle = 0;
+    WXDWORD exStyle = 0;
     DWORD wstyle = MSWGetStyle(m_windowStyle, & exStyle);
     wstyle |= WS_TABSTOP | TVS_SHOWSELALWAYS;
 
@@ -699,20 +680,6 @@ bool wxTreeCtrl::Create(wxWindow *parent,
             wstyle |= TVS_FULLROWSELECT;
     }
 
-    // using TVS_CHECKBOXES for emulation of a multiselection tree control
-    // doesn't work without the new enough headers
-#if wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE && \
-    !defined( __GNUWIN32_OLD__ ) && \
-    !defined( __BORLANDC__ ) && \
-    !defined( __WATCOMC__ ) && \
-    (!defined(__VISUALC__) || (__VISUALC__ > 1010))
-
-    // we emulate the multiple selection tree controls by using checkboxes: set
-    // up the image list we need for this if we do have multiple selections
-    if ( m_windowStyle & wxTR_MULTIPLE )
-        wstyle |= TVS_CHECKBOXES;
-#endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-
 #if !defined(__WXWINCE__) && defined(TVS_INFOTIP)
     // Need so that TVN_GETINFOTIP messages will be sent
     wstyle |= TVS_INFOTIP;
@@ -1750,11 +1717,7 @@ void wxTreeCtrl::UnselectAll()
         size_t count = GetSelections(selections);
         for ( size_t n = 0; n < count; n++ )
         {
-#if wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-            SetItemCheck(HITEM(selections[n]), false);
-#else // !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
             ::UnselectItem(GetHwnd(), HITEM(selections[n]));
-#endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE/!wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
         }
 
         m_htSelStart.Unset();
@@ -1770,12 +1733,7 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select)
 {
     if ( m_windowStyle & wxTR_MULTIPLE )
     {
-#if wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-        // selecting the item means checking it
-        SetItemCheck(item, select);
-#else // !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
         ::SelectItem(GetHwnd(), HITEM(item), select);
-#endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE/!wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
     }
     else
     {
@@ -2059,7 +2017,7 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
         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))
+        if (ItemRect.Contains(MenuPoint))
         {
             event.m_pointDrag = MenuPoint;
         }
@@ -2092,22 +2050,6 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
 
         switch ( nMsg )
         {
-            case WM_RBUTTONDOWN:
-                // if the item we are about to right click on is not already
-                // selected or if we click outside of any item, remove the
-                // entire previous selection
-                if ( !htItem || !::IsItemSelected(GetHwnd(), htItem) )
-                {
-                    UnselectAll();
-                }
-
-                // select item and set the focus to the
-                // newly selected item
-                ::SelectItem(GetHwnd(), htItem);
-                ::SetFocus(GetHwnd(), htItem);
-                break;
-
-#if !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
             case WM_LBUTTONDOWN:
                 if ( htItem && isMultiple && (tvht.flags & TVHT_ONITEM) != 0 )
                 {
@@ -2188,7 +2130,6 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
                     }
                 }
                 break;
-#endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
 
             case WM_MOUSEMOVE:
 #ifndef __WXWINCE__
@@ -2284,7 +2225,6 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
                 break;
         }
     }
-#if !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
     else if ( (nMsg == WM_SETFOCUS || nMsg == WM_KILLFOCUS) && isMultiple )
     {
         // the tree control greys out the selected item when it loses focus and
@@ -2384,7 +2324,6 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
                 }
         }
     }
-#endif // !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
     else if ( nMsg == WM_COMMAND )
     {
         // if we receive a EN_KILLFOCUS command from the in-place edit control
@@ -2413,32 +2352,9 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
 WXLRESULT
 wxTreeCtrl::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 {
-    // default WM_RBUTTONDOWN handler enters modal loop inside DefWindowProc()
-    // waiting for WM_RBUTTONUP and then sends the resulting WM_CONTEXTMENU to
-    // the parent window, not us, which completely breaks everything so simply
-    // don't let it see this message at all
-    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
+        // 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
@@ -2549,8 +2465,8 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
                 break;
             }
-#endif
-#endif
+#endif // TVN_GETINFOTIP
+#endif // !__WXWINCE__
 
         case TVN_GETDISPINFO:
             eventType = wxEVT_COMMAND_TREE_GET_INFO;
@@ -2821,6 +2737,17 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
             *result = false;
             break;
 
+        case NM_RCLICK:
+            // prevent tree control from sending WM_CONTEXTMENU to our parent
+            // (which it does if NM_RCLICK is not handled) because we want to
+            // send it to the control itself
+            *result =
+            processed = true;
+
+            ::SendMessage(GetHwnd(), WM_CONTEXTMENU,
+                          (WPARAM)GetHwnd(), ::GetMessagePos());
+            break;
+
         case TVN_BEGINDRAG:
         case TVN_BEGINRDRAG:
             if ( event.IsAllowed() )