]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/listctrl.cpp
reset m_selectionOld when the selection is programatically changed
[wxWidgets.git] / src / msw / listctrl.cpp
index 3c08663e15bf4dbd2d00fd0329db714b9c04b8ff..0d5621a969a2bb22e01cf19d518a4debe8158f77 100644 (file)
@@ -121,7 +121,7 @@ public:
 
         // memcpy() can't work if the struct sizes are different
         wxCOMPILE_TIME_ASSERT( sizeof(LV_ITEM_OTHER) == sizeof(LV_ITEM_NATIVE),
-                                CodeCantWorkIfDiffSizes);
+                               CodeCantWorkIfDiffSizes);
 
         memcpy(&m_item, &item, sizeof(LV_ITEM_NATIVE));
 
@@ -221,8 +221,10 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS)
+#if WXWIN_COMPATIBILITY_2_4
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO)
+#endif
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN)
@@ -478,6 +480,8 @@ void wxListCtrl::FreeAllInternalData()
         m_ignoreChangeMessages = false;
 
         m_AnyInternalData = false;
+
+        m_count = 0;
     }
 }
 
@@ -938,7 +942,7 @@ void wxListCtrl::SetItemText(long item, const wxString& str)
 }
 
 // Gets the item data
-long wxListCtrl::GetItemData(long item) const
+wxUIntPtr wxListCtrl::GetItemData(long item) const
 {
     wxListItem info;
 
@@ -1260,7 +1264,6 @@ bool wxListCtrl::DeleteItem(long item)
 // Deletes all items
 bool wxListCtrl::DeleteAllItems()
 {
-    FreeAllInternalData();
     return ListView_DeleteAllItems(GetHwnd()) != 0;
 }
 
@@ -1376,7 +1379,7 @@ long wxListCtrl::FindItem(long start, const wxString& str, bool partial)
 // NOTE : Lindsay Mathieson - 14-July-2002
 //        No longer use ListView_FindItem as the data attribute is now stored
 //        in a wxListItemInternalData structure refernced by the actual lParam
-long wxListCtrl::FindItem(long start, long data)
+long wxListCtrl::FindItem(long start, wxUIntPtr data)
 {
     long  idx = start + 1;
     long count = GetItemCount();
@@ -1425,23 +1428,38 @@ long wxListCtrl::HitTest(const wxPoint& point, int& flags)
     ListView_HitTest(GetHwnd(), & hitTestInfo);
 
     flags = 0;
+
     if ( hitTestInfo.flags & LVHT_ABOVE )
         flags |= wxLIST_HITTEST_ABOVE;
     if ( hitTestInfo.flags & LVHT_BELOW )
         flags |= wxLIST_HITTEST_BELOW;
-    if ( hitTestInfo.flags & LVHT_NOWHERE )
-        flags |= wxLIST_HITTEST_NOWHERE;
-    if ( hitTestInfo.flags & LVHT_ONITEMICON )
-        flags |= wxLIST_HITTEST_ONITEMICON;
-    if ( hitTestInfo.flags & LVHT_ONITEMLABEL )
-        flags |= wxLIST_HITTEST_ONITEMLABEL;
-    if ( hitTestInfo.flags & LVHT_ONITEMSTATEICON )
-        flags |= wxLIST_HITTEST_ONITEMSTATEICON;
     if ( hitTestInfo.flags & LVHT_TOLEFT )
         flags |= wxLIST_HITTEST_TOLEFT;
     if ( hitTestInfo.flags & LVHT_TORIGHT )
         flags |= wxLIST_HITTEST_TORIGHT;
 
+    if ( hitTestInfo.flags & LVHT_NOWHERE )
+        flags |= wxLIST_HITTEST_NOWHERE;
+
+    // note a bug or at least a very strange feature of comtl32.dll (tested
+    // with version 4.0 under Win95 and 6.0 under Win 2003): if you click to
+    // the right of the item label, ListView_HitTest() returns a combination of
+    // LVHT_ONITEMICON, LVHT_ONITEMLABEL and LVHT_ONITEMSTATEICON -- filter out
+    // the bits which don't make sense
+    if ( hitTestInfo.flags & LVHT_ONITEMLABEL )
+    {
+        flags |= wxLIST_HITTEST_ONITEMLABEL;
+
+        // do not translate LVHT_ONITEMICON here, as per above
+    }
+    else
+    {
+        if ( hitTestInfo.flags & LVHT_ONITEMICON )
+            flags |= wxLIST_HITTEST_ONITEMICON;
+        if ( hitTestInfo.flags & LVHT_ONITEMSTATEICON )
+            flags |= wxLIST_HITTEST_ONITEMSTATEICON;
+    }
+
     return (long) hitTestInfo.iItem;
 }
 
@@ -1772,20 +1790,15 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 break;
 
             case HDN_GETDISPINFOW:
-                {
-                    LPNMHDDISPINFOW info = (LPNMHDDISPINFOW) lParam;
-                    // This is a fix for a strange bug under XP.
-                    // Normally, info->iItem is a valid index, but
-                    // sometimes this is a silly (large) number
-                    // and when we return false via wxControl::MSWOnNotify
-                    // to indicate that it hasn't yet been processed,
-                    // there's a GPF in Windows.
-                    // By returning true here, we avoid further processing
-                    // of this strange message.
-                    if ( (unsigned)info->iItem >= (unsigned)GetColumnCount() )
-                        return true;
-                }
-                // fall through
+                // letting Windows XP handle this message results in mysterious
+                // crashes in comctl32.dll seemingly because of bad message
+                // parameters
+                //
+                // I have no idea what is the real cause of the bug (which is,
+                // just to make things interesting, is impossible to reproduce
+                // reliably) but ignoring all these messages does fix it and
+                // doesn't seem to have any negative consequences
+                return true;
 
             default:
                 return wxControl::MSWOnNotify(idCtrl, lParam, result);
@@ -1906,7 +1919,6 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 break;
 
             case LVN_DELETEALLITEMS:
-                m_count = 0;
                 eventType = wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS;
                 event.m_itemIndex = -1;
                 break;
@@ -1923,6 +1935,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 wxDeleteInternalData(this, iItem);
                 break;
 
+#if WXWIN_COMPATIBILITY_2_4
             case LVN_SETDISPINFO:
                 {
                     eventType = wxEVT_COMMAND_LIST_SET_INFO;
@@ -1930,6 +1943,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                     wxConvertFromMSWListItem(GetHwnd(), event.m_item, info->item);
                 }
                 break;
+#endif
 
             case LVN_INSERTITEM:
                 eventType = wxEVT_COMMAND_LIST_INSERT_ITEM;
@@ -2175,6 +2189,10 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
             // notifications - this makes deleting all items from a list ctrl
             // much faster
             *result = TRUE;
+
+            // also, we may free all user data now (couldn't do it before as
+            // the user should have access to it in OnDeleteAllItems() handler)
+            FreeAllInternalData();
             return true;
 
         case LVN_ENDLABELEDITA:
@@ -2374,9 +2392,9 @@ wxString wxListCtrl::OnGetItemText(long WXUNUSED(item), long WXUNUSED(col)) cons
 
 int wxListCtrl::OnGetItemImage(long WXUNUSED(item)) const
 {
-    // same as above
-    wxFAIL_MSG( _T("wxListCtrl::OnGetItemImage not supposed to be called") );
-
+    wxCHECK_MSG(!GetImageList(wxIMAGE_LIST_SMALL),
+                -1,
+                wxT("List control has an image list, OnGetItemImage should be overridden."));
     return -1;
 }