]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/listctrl.cpp
Swap client data pointers in wxRearrangeList too.
[wxWidgets.git] / src / msw / listctrl.cpp
index 93eebf755c7d098516c32854aff19456bf5db15c..484443466f86dc586a619bf350308a9f9bfee950 100644 (file)
@@ -497,8 +497,7 @@ void wxListCtrl::DeleteEditControl()
     {
         m_textCtrl->UnsubclassWin();
         m_textCtrl->SetHWND(0);
-        delete m_textCtrl;
-        m_textCtrl = NULL;
+        wxDELETE(m_textCtrl);
     }
 }
 
@@ -1031,12 +1030,13 @@ bool wxListCtrl::SetItemColumnImage(long item, long column, int image)
 }
 
 // Gets the item text
-wxString wxListCtrl::GetItemText(long item) const
+wxString wxListCtrl::GetItemText(long item, int col) const
 {
     wxListItem info;
 
     info.m_mask = wxLIST_MASK_TEXT;
     info.m_itemId = item;
+    info.m_col = col;
 
     if (!GetItem(info))
         return wxEmptyString;
@@ -1183,7 +1183,7 @@ bool wxListCtrl::GetSubItemRect(long item, long subItem, wxRect& rect, int code)
     // there is no way to retrieve the first sub item bounding rectangle using
     // wxGetListCtrlSubItemRect() as 0 means the whole item, so we need to
     // truncate it at first column ourselves
-    if ( subItem == 0 )
+    if ( subItem == 0 && code == wxLIST_RECT_BOUNDS )
         rect.width = GetColumnWidth(0);
 
     return true;
@@ -1538,8 +1538,7 @@ wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass)
     if ( !hWnd )
     {
         // failed to start editing
-        delete m_textCtrl;
-        m_textCtrl = NULL;
+        wxDELETE(m_textCtrl);
 
         return NULL;
     }
@@ -1560,14 +1559,21 @@ bool wxListCtrl::EndEditLabel(bool cancel)
     if ( !hwnd )
         return false;
 
-    if ( cancel )
-        ::SetWindowText(hwnd, wxEmptyString); // dubious but better than nothing
-
-    // we shouldn't destroy the control ourselves according to MSDN, which
-    // proposes WM_CANCELMODE to do this, but it doesn't seem to work
-    //
-    // posting WM_CLOSE to it does seem to work without any side effects
-    ::PostMessage(hwnd, WM_CLOSE, 0, 0);
+    // Newer versions of Windows have a special message for cancelling editing,
+    // use it if available.
+#ifdef ListView_CancelEditLabel
+    if ( cancel && (wxApp::GetComCtl32Version() >= 600) )
+    {
+        ListView_CancelEditLabel(GetHwnd());
+    }
+    else
+#endif // ListView_CancelEditLabel
+    {
+        // We shouldn't destroy the control ourselves according to MSDN, which
+        // proposes WM_CANCELMODE to do this, but it doesn't seem to work so
+        // emulate the corresponding user action instead.
+        ::SendMessage(hwnd, WM_KEYDOWN, cancel ? VK_ESCAPE : VK_RETURN, 0);
+    }
 
     return true;
 }
@@ -1753,7 +1759,10 @@ long wxListCtrl::InsertItem(const wxListItem& info)
         }
     }
 
-    long rv = ListView_InsertItem(GetHwnd(), & item);
+    const long rv = ListView_InsertItem(GetHwnd(), & item);
+
+    // failing to insert the item is really unexpected
+    wxCHECK_MSG( rv != -1, rv, "failed to insert an item in wxListCtrl" );
 
     m_count++;
     wxASSERT_MSG( m_count == ListView_GetItemCount(GetHwnd()),
@@ -2026,29 +2035,50 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
         event.m_itemIndex = -1;
 
+        bool ignore = false;
         switch ( nmhdr->code )
         {
             // yet another comctl32.dll bug: under NT/W2K it sends Unicode
             // TRACK messages even to ANSI programs: on my system I get
-            // HDN_BEGINTRACKW and HDN_ENDTRACKA and no HDN_TRACK at all!
+            // HDN_BEGINTRACKW and HDN_ENDTRACKA!
             //
             // work around is to simply catch both versions and hope that it
             // works (why should this message exist in ANSI and Unicode is
             // beyond me as it doesn't deal with strings at all...)
             //
-            // note that fr HDN_TRACK another possibility could be to use
-            // HDN_ITEMCHANGING but it is sent even after HDN_ENDTRACK and when
-            // something other than the item width changes so we'd have to
-            // filter out the unwanted events then
+            // another problem is that HDN_TRACK is not sent at all by header
+            // with HDS_FULLDRAG style which is used by default by wxListCtrl
+            // under recent Windows versions (starting from at least XP) so we
+            // need to use HDN_ITEMCHANGING instead of it
             case HDN_BEGINTRACKA:
             case HDN_BEGINTRACKW:
                 eventType = wxEVT_COMMAND_LIST_COL_BEGIN_DRAG;
                 // fall through
 
-            case HDN_TRACKA:
-            case HDN_TRACKW:
+            case HDN_ITEMCHANGING:
                 if ( eventType == wxEVT_NULL )
+                {
+                    if ( !nmHDR->pitem || !(nmHDR->pitem->mask & HDI_WIDTH) )
+                    {
+                        // something other than the width is being changed,
+                        // ignore it
+                        ignore = true;
+                        break;
+                    }
+
+                    // also ignore the events sent when the width didn't really
+                    // change: this is not just an optimization but also gets
+                    // rid of a useless and unexpected DRAGGING event which
+                    // would otherwise be sent after the END_DRAG one as we get
+                    // an HDN_ITEMCHANGING after HDN_ENDTRACK for some reason
+                    if ( nmHDR->pitem->cxy == GetColumnWidth(nmHDR->iItem) )
+                    {
+                        ignore = true;
+                        break;
+                    }
+
                     eventType = wxEVT_COMMAND_LIST_COL_DRAGGING;
+                }
                 // fall through
 
             case HDN_ENDTRACKA:
@@ -2086,8 +2116,11 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 return true;
 
             default:
-                return wxControl::MSWOnNotify(idCtrl, lParam, result);
+                ignore = true;
         }
+
+        if ( ignore )
+            return wxControl::MSWOnNotify(idCtrl, lParam, result);
     }
     else
 #endif // defined(HDN_BEGINTRACKA)
@@ -2211,8 +2244,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                         if ( m_internalData[n] == data )
                         {
                             m_internalData.erase(m_internalData.begin() + n);
-                            delete data;
-                            data = NULL;
+                            wxDELETE(data);
                             break;
                         }
                     }
@@ -2451,7 +2483,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                         // wrap to the beginning if necessary
                         if ( currentPos == maxPos )
                         {
-                            // somewhat surprizingly, LVFI_WRAP isn't set in
+                            // somewhat surprisingly, LVFI_WRAP isn't set in
                             // flags but we still should wrap
                             currentPos = 0;
                         }