Final (hopefully) version of the DeleteAllItems fix for 2.4
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@18881 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -53,6 +53,24 @@
|
|||||||
|
|
||||||
#include "wx/msw/missing.h"
|
#include "wx/msw/missing.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// private globals (yuck!)
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Some versions of comctl32.dll don't do what MSDN says it should and still
|
||||||
|
// sends LVN_DELETEITEM after LVN_DELETEALLITEMS has returned TRUE. This flag
|
||||||
|
// will be used to enable us to ignore the LVN_DELETEITEM message in these cases.
|
||||||
|
// Also note that sometimes when there are large numbers of items in the listctrl
|
||||||
|
// and items have attribute data then when the data is being deleted a
|
||||||
|
// LVN_ITEMCHANGING message can be sent that will have a bogus value, causing a
|
||||||
|
// memory fault. This flag will also be used to ignore those change messages.
|
||||||
|
//
|
||||||
|
// 2.5 will have a better fix that avoids the use of a global. It was unavoidable
|
||||||
|
// for 2.4.x because of binary compatibility concerns.
|
||||||
|
static bool gs_ignoreChangeDeleteItem = FALSE;
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// private functions
|
// private functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -388,7 +406,9 @@ void wxListCtrl::FreeAllInternalData()
|
|||||||
|
|
||||||
wxListCtrl::~wxListCtrl()
|
wxListCtrl::~wxListCtrl()
|
||||||
{
|
{
|
||||||
|
gs_ignoreChangeDeleteItem = TRUE;
|
||||||
FreeAllInternalData();
|
FreeAllInternalData();
|
||||||
|
gs_ignoreChangeDeleteItem = FALSE;
|
||||||
|
|
||||||
if ( m_textCtrl )
|
if ( m_textCtrl )
|
||||||
{
|
{
|
||||||
@@ -1233,7 +1253,11 @@ bool wxListCtrl::DeleteItem(long item)
|
|||||||
// Deletes all items
|
// Deletes all items
|
||||||
bool wxListCtrl::DeleteAllItems()
|
bool wxListCtrl::DeleteAllItems()
|
||||||
{
|
{
|
||||||
return ListView_DeleteAllItems(GetHwnd()) != 0;
|
gs_ignoreChangeDeleteItem = TRUE;
|
||||||
|
FreeAllInternalData();
|
||||||
|
bool rval = ListView_DeleteAllItems(GetHwnd()) != 0;
|
||||||
|
gs_ignoreChangeDeleteItem = FALSE;
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deletes all items
|
// Deletes all items
|
||||||
@@ -1641,10 +1665,6 @@ bool wxListCtrl::MSWCommand(WXUINT cmd, WXWORD id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Prevent fetching item data when in the process of deleting it. See
|
|
||||||
// wxDeleteInternalData below.
|
|
||||||
static bool gs_deletingItemData = FALSE;
|
|
||||||
|
|
||||||
bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||||
{
|
{
|
||||||
// prepare the event
|
// prepare the event
|
||||||
@@ -1787,7 +1807,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
case LVN_ITEMCHANGING:
|
case LVN_ITEMCHANGING:
|
||||||
if ( iItem != -1 )
|
if ( iItem != -1 )
|
||||||
{
|
{
|
||||||
if ( iItem >= GetItemCount() || gs_deletingItemData )
|
if ( iItem >= GetItemCount() || gs_ignoreChangeDeleteItem )
|
||||||
{
|
{
|
||||||
// there is apparently a bug in comctl32.dll version
|
// there is apparently a bug in comctl32.dll version
|
||||||
// 5.50.4704.1100 (note that the MS DLL database
|
// 5.50.4704.1100 (note that the MS DLL database
|
||||||
@@ -1896,6 +1916,9 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LVN_DELETEITEM:
|
case LVN_DELETEITEM:
|
||||||
|
if ( gs_ignoreChangeDeleteItem )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
eventType = wxEVT_COMMAND_LIST_DELETE_ITEM;
|
eventType = wxEVT_COMMAND_LIST_DELETE_ITEM;
|
||||||
event.m_itemIndex = iItem;
|
event.m_itemIndex = iItem;
|
||||||
// delete the assoicated internal data
|
// delete the assoicated internal data
|
||||||
@@ -2444,9 +2467,7 @@ static void wxDeleteInternalData(wxListCtrl* ctl, long itemId)
|
|||||||
item.iItem = itemId;
|
item.iItem = itemId;
|
||||||
item.mask = LVIF_PARAM;
|
item.mask = LVIF_PARAM;
|
||||||
item.lParam = (LPARAM) 0;
|
item.lParam = (LPARAM) 0;
|
||||||
gs_deletingItemData = TRUE;
|
|
||||||
ListView_SetItem((HWND)ctl->GetHWND(), &item);
|
ListView_SetItem((HWND)ctl->GetHWND(), &item);
|
||||||
gs_deletingItemData = FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user