]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/listctrl.cpp
end label editing if the control loses focus (slightly modified patch 1084592)
[wxWidgets.git] / src / msw / listctrl.cpp
index 9f16e8d09d5c28eaceb805601ad411241870ad5c..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)
@@ -447,9 +449,17 @@ void wxListCtrl::UpdateStyle()
         // The new window view style
         DWORD dwStyleNew = MSWGetStyle(m_windowStyle, NULL);
 
+        // some styles are not returned by MSWGetStyle()
+        if ( IsShown() )
+            dwStyleNew |= WS_VISIBLE;
+
         // Get the current window style.
         DWORD dwStyleOld = ::GetWindowLong(GetHwnd(), GWL_STYLE);
 
+        // we don't have wxVSCROLL style, but the list control may have it,
+        // don't change it then
+        dwStyleNew |= dwStyleOld & (WS_HSCROLL | WS_VSCROLL);
+
         // Only set the window style if the view bits have changed.
         if ( dwStyleOld != dwStyleNew )
         {
@@ -470,6 +480,8 @@ void wxListCtrl::FreeAllInternalData()
         m_ignoreChangeMessages = false;
 
         m_AnyInternalData = false;
+
+        m_count = 0;
     }
 }
 
@@ -510,30 +522,25 @@ void wxListCtrl::SetSingleStyle(long style, bool add)
             flag = flag & ~wxLC_MASK_SORT;
     }
 
-    if ( flag & style )
-    {
-        if ( !add )
-            flag -= style;
-    }
+    if ( add )
+        flag |= style;
     else
-    {
-        if ( add )
-        {
-            flag |= style;
-        }
-    }
-
-    m_windowStyle = flag;
+        flag &= ~style;
 
-    UpdateStyle();
+    SetWindowStyleFlag(flag);
 }
 
 // Set the whole window style
 void wxListCtrl::SetWindowStyleFlag(long flag)
 {
-    m_windowStyle = flag;
+    if ( flag != m_windowStyle )
+    {
+        m_windowStyle = flag;
 
-    UpdateStyle();
+        UpdateStyle();
+
+        Refresh();
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -935,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;
 
@@ -1257,7 +1264,6 @@ bool wxListCtrl::DeleteItem(long item)
 // Deletes all items
 bool wxListCtrl::DeleteAllItems()
 {
-    FreeAllInternalData();
     return ListView_DeleteAllItems(GetHwnd()) != 0;
 }
 
@@ -1373,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();
@@ -1422,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;
 }
 
@@ -1743,7 +1764,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                         wxLogLastError(_T("GetCursorPos"));
                     }
 
-                    if ( !::ScreenToClient(hwndHdr, &ptClick) )
+                    if ( !::ScreenToClient(GetHwnd(), &ptClick) )
                     {
                         wxLogLastError(_T("ScreenToClient(listctrl header)"));
                     }
@@ -1769,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);
@@ -1903,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;
@@ -1920,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;
@@ -1927,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;
@@ -2172,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:
@@ -2371,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;
 }