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
This commit is contained in:
@@ -79,7 +79,7 @@ static void wxConvertToMSWListCol(int col, const wxListItem& item,
|
|||||||
|
|
||||||
// We have to handle both fooW and fooA notifications in several cases
|
// 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
|
// 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
|
// LV_ITEMW depending on wxUSE_UNICODE setting), so that it can be processed
|
||||||
// by wxConvertToMSWListItem().
|
// by wxConvertToMSWListItem().
|
||||||
class wxLV_ITEM
|
class wxLV_ITEM
|
||||||
@@ -100,7 +100,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_buf = NULL;
|
m_buf = NULL;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
wxMB2WXbuf *m_buf;
|
wxMB2WXbuf *m_buf;
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ private:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_buf = NULL;
|
m_buf = NULL;
|
||||||
}
|
}
|
||||||
wxLV_ITEM(LV_ITEMA &item) : m_buf(NULL), m_item(&item) {}
|
wxLV_ITEM(LV_ITEMA &item) : m_buf(NULL), m_item(&item) {}
|
||||||
private:
|
private:
|
||||||
wxWC2WXbuf *m_buf;
|
wxWC2WXbuf *m_buf;
|
||||||
@@ -126,32 +126,32 @@ private:
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// Problem:
|
// Problem:
|
||||||
// The MSW version had problems with SetTextColour() et
|
// The MSW version had problems with SetTextColour() et
|
||||||
// al as the wxListItemAttr's were stored keyed on the
|
// al as the wxListItemAttr's were stored keyed on the
|
||||||
// item index. If a item was inserted anywhere but the end
|
// item index. If a item was inserted anywhere but the end
|
||||||
// of the list the the text attributes (colour etc) for
|
// of the list the the text attributes (colour etc) for
|
||||||
// the following items were out of sync.
|
// the following items were out of sync.
|
||||||
//
|
//
|
||||||
// Solution:
|
// Solution:
|
||||||
// Under MSW the only way to associate data with a List
|
// Under MSW the only way to associate data with a List
|
||||||
// item independant of its position in the list is to
|
// item independant of its position in the list is to
|
||||||
// store a pointer to it in its lParam attribute. However
|
// store a pointer to it in its lParam attribute. However
|
||||||
// user programs are already using this (via the
|
// user programs are already using this (via the
|
||||||
// SetItemData() GetItemData() calls).
|
// SetItemData() GetItemData() calls).
|
||||||
//
|
//
|
||||||
// However what we can do is store a pointer to a
|
// However what we can do is store a pointer to a
|
||||||
// structure which contains the attributes we want *and*
|
// structure which contains the attributes we want *and*
|
||||||
// a lParam for the users data, e.g.
|
// a lParam for the users data, e.g.
|
||||||
//
|
//
|
||||||
// class wxListItemInternalData
|
// class wxListItemInternalData
|
||||||
// {
|
// {
|
||||||
// public:
|
// public:
|
||||||
// wxListItemAttr *attr;
|
// wxListItemAttr *attr;
|
||||||
// long lParam; // user data
|
// long lParam; // user data
|
||||||
// };
|
// };
|
||||||
//
|
//
|
||||||
// To conserve memory, a wxListItemInternalData is
|
// To conserve memory, a wxListItemInternalData is
|
||||||
// only allocated for a LV_ITEM if text attributes or
|
// only allocated for a LV_ITEM if text attributes or
|
||||||
// user data(lparam) are being set.
|
// user data(lparam) are being set.
|
||||||
|
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ private:
|
|||||||
class wxListItemInternalData
|
class wxListItemInternalData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxListItemAttr *attr;
|
wxListItemAttr *attr;
|
||||||
LPARAM lParam; // user data
|
LPARAM lParam; // user data
|
||||||
|
|
||||||
wxListItemInternalData() : attr(NULL), lParam(0) {}
|
wxListItemInternalData() : attr(NULL), lParam(0) {}
|
||||||
@@ -359,7 +359,7 @@ void wxListCtrl::UpdateStyle()
|
|||||||
void wxListCtrl::FreeAllInternalData()
|
void wxListCtrl::FreeAllInternalData()
|
||||||
{
|
{
|
||||||
if (m_AnyInternalData)
|
if (m_AnyInternalData)
|
||||||
{
|
{
|
||||||
int n = GetItemCount();
|
int n = GetItemCount();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -367,9 +367,18 @@ void wxListCtrl::FreeAllInternalData()
|
|||||||
{
|
{
|
||||||
wxListItemInternalData *data = GetInternalData(this, i);
|
wxListItemInternalData *data = GetInternalData(this, i);
|
||||||
if (data)
|
if (data)
|
||||||
|
{
|
||||||
delete 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()
|
wxListCtrl::~wxListCtrl()
|
||||||
@@ -724,7 +733,7 @@ bool wxListCtrl::SetItem(wxListItem& info)
|
|||||||
// get internal item data
|
// get internal item data
|
||||||
// perhaps a cache here ?
|
// perhaps a cache here ?
|
||||||
wxListItemInternalData *data = GetInternalData(this, info.m_itemId);
|
wxListItemInternalData *data = GetInternalData(this, info.m_itemId);
|
||||||
|
|
||||||
if (! data)
|
if (! data)
|
||||||
{
|
{
|
||||||
// need to set it
|
// need to set it
|
||||||
@@ -1196,6 +1205,7 @@ bool wxListCtrl::DeleteItem(long item)
|
|||||||
// Deletes all items
|
// Deletes all items
|
||||||
bool wxListCtrl::DeleteAllItems()
|
bool wxListCtrl::DeleteAllItems()
|
||||||
{
|
{
|
||||||
|
FreeAllInternalData();
|
||||||
return ListView_DeleteAllItems(GetHwnd()) != 0;
|
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;
|
eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
|
||||||
wxLV_ITEM item(((LV_DISPINFOA *)lParam)->item);
|
wxLV_ITEM item(((LV_DISPINFOA *)lParam)->item);
|
||||||
wxConvertFromMSWListItem(NULL, event.m_item, item);
|
wxConvertFromMSWListItem(NULL, event.m_item, item);
|
||||||
if ( ((LV_ITEM)item).pszText == NULL ||
|
if ( ((LV_ITEM)item).pszText == NULL ||
|
||||||
((LV_ITEM)item).iItem == -1 )
|
((LV_ITEM)item).iItem == -1 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -1740,7 +1750,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
|
eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
|
||||||
wxLV_ITEM item(((LV_DISPINFOW *)lParam)->item);
|
wxLV_ITEM item(((LV_DISPINFOW *)lParam)->item);
|
||||||
wxConvertFromMSWListItem(NULL, event.m_item, item);
|
wxConvertFromMSWListItem(NULL, event.m_item, item);
|
||||||
if ( ((LV_ITEM)item).pszText == NULL ||
|
if ( ((LV_ITEM)item).pszText == NULL ||
|
||||||
((LV_ITEM)item).iItem == -1 )
|
((LV_ITEM)item).iItem == -1 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -1765,7 +1775,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
|
|
||||||
// delete the assoicated internal data
|
// delete the assoicated internal data
|
||||||
{
|
{
|
||||||
wxListItemInternalData *data =
|
wxListItemInternalData *data =
|
||||||
GetInternalData(this, nmLV->iItem);
|
GetInternalData(this, nmLV->iItem);
|
||||||
if (data)
|
if (data)
|
||||||
delete data;
|
delete data;
|
||||||
@@ -2289,7 +2299,7 @@ static void wxConvertFromMSWListItem(HWND hwndListCtrl,
|
|||||||
wxListItem& info,
|
wxListItem& info,
|
||||||
LV_ITEM& lvItem)
|
LV_ITEM& lvItem)
|
||||||
{
|
{
|
||||||
wxListItemInternalData *internaldata =
|
wxListItemInternalData *internaldata =
|
||||||
(wxListItemInternalData *) lvItem.lParam;
|
(wxListItemInternalData *) lvItem.lParam;
|
||||||
|
|
||||||
if (internaldata)
|
if (internaldata)
|
||||||
|
Reference in New Issue
Block a user