From: Robin Dunn Date: Fri, 21 Jun 2002 01:57:17 +0000 (+0000) Subject: This fixes a crash that would happen when DeleteAllItems is called X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/73d8c5fd7620fd5eea3bc37de587473e14cff01e This fixes a crash that would happen when DeleteAllItems is called when some items have attributes. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15902 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index ff95a5ce0e..cae8ad8d26 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -79,7 +79,7 @@ static void wxConvertToMSWListCol(int col, const wxListItem& item, // We have to handle both fooW and fooA notifications in several cases // because of broken commctl.dll and/or unicows.dll. This class is used to -// convert LV_ITEMA and LV_ITEMW to LV_ITEM (which is either LV_ITEMA or +// convert LV_ITEMA and LV_ITEMW to LV_ITEM (which is either LV_ITEMA or // LV_ITEMW depending on wxUSE_UNICODE setting), so that it can be processed // by wxConvertToMSWListItem(). class wxLV_ITEM @@ -100,7 +100,7 @@ public: } else m_buf = NULL; - } + } private: wxMB2WXbuf *m_buf; @@ -115,7 +115,7 @@ private: } else m_buf = NULL; - } + } wxLV_ITEM(LV_ITEMA &item) : m_buf(NULL), m_item(&item) {} private: wxWC2WXbuf *m_buf; @@ -126,32 +126,32 @@ private: /////////////////////////////////////////////////////// // Problem: -// The MSW version had problems with SetTextColour() et -// al as the wxListItemAttr's were stored keyed on the -// item index. If a item was inserted anywhere but the end -// of the list the the text attributes (colour etc) for +// The MSW version had problems with SetTextColour() et +// al as the wxListItemAttr's were stored keyed on the +// item index. If a item was inserted anywhere but the end +// of the list the the text attributes (colour etc) for // the following items were out of sync. -// +// // Solution: -// Under MSW the only way to associate data with a List -// item independant of its position in the list is to -// store a pointer to it in its lParam attribute. However -// user programs are already using this (via the +// Under MSW the only way to associate data with a List +// item independant of its position in the list is to +// store a pointer to it in its lParam attribute. However +// user programs are already using this (via the // SetItemData() GetItemData() calls). -// -// However what we can do is store a pointer to a -// structure which contains the attributes we want *and* +// +// However what we can do is store a pointer to a +// structure which contains the attributes we want *and* // a lParam for the users data, e.g. -// +// // class wxListItemInternalData // { // public: -// wxListItemAttr *attr; +// wxListItemAttr *attr; // long lParam; // user data // }; -// -// To conserve memory, a wxListItemInternalData is -// only allocated for a LV_ITEM if text attributes or +// +// To conserve memory, a wxListItemInternalData is +// only allocated for a LV_ITEM if text attributes or // user data(lparam) are being set. @@ -159,7 +159,7 @@ private: class wxListItemInternalData { public: - wxListItemAttr *attr; + wxListItemAttr *attr; LPARAM lParam; // user data wxListItemInternalData() : attr(NULL), lParam(0) {} @@ -359,7 +359,7 @@ void wxListCtrl::UpdateStyle() void wxListCtrl::FreeAllInternalData() { if (m_AnyInternalData) - { + { int n = GetItemCount(); int i = 0; @@ -367,9 +367,18 @@ void wxListCtrl::FreeAllInternalData() { wxListItemInternalData *data = GetInternalData(this, i); if (data) + { delete data; - }; - }; + LV_ITEM item; + memset(&item, 0, sizeof(item)); + item.iItem = i; + item.mask = LVIF_PARAM; + item.lParam = (LPARAM) 0; + BOOL result = ListView_SetItem(GetHwnd(), &item); + } + } + m_AnyInternalData = FALSE; + } } wxListCtrl::~wxListCtrl() @@ -724,7 +733,7 @@ bool wxListCtrl::SetItem(wxListItem& info) // get internal item data // perhaps a cache here ? wxListItemInternalData *data = GetInternalData(this, info.m_itemId); - + if (! data) { // need to set it @@ -1196,6 +1205,7 @@ bool wxListCtrl::DeleteItem(long item) // Deletes all items bool wxListCtrl::DeleteAllItems() { + FreeAllInternalData(); return ListView_DeleteAllItems(GetHwnd()) != 0; } @@ -1728,7 +1738,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT; wxLV_ITEM item(((LV_DISPINFOA *)lParam)->item); wxConvertFromMSWListItem(NULL, event.m_item, item); - if ( ((LV_ITEM)item).pszText == NULL || + if ( ((LV_ITEM)item).pszText == NULL || ((LV_ITEM)item).iItem == -1 ) return FALSE; @@ -1740,7 +1750,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT; wxLV_ITEM item(((LV_DISPINFOW *)lParam)->item); wxConvertFromMSWListItem(NULL, event.m_item, item); - if ( ((LV_ITEM)item).pszText == NULL || + if ( ((LV_ITEM)item).pszText == NULL || ((LV_ITEM)item).iItem == -1 ) return FALSE; @@ -1765,7 +1775,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // delete the assoicated internal data { - wxListItemInternalData *data = + wxListItemInternalData *data = GetInternalData(this, nmLV->iItem); if (data) delete data; @@ -2289,7 +2299,7 @@ static void wxConvertFromMSWListItem(HWND hwndListCtrl, wxListItem& info, LV_ITEM& lvItem) { - wxListItemInternalData *internaldata = + wxListItemInternalData *internaldata = (wxListItemInternalData *) lvItem.lParam; if (internaldata)