Hi Robin et al,
I think I may have discovered a bug in wx.TreeListCtrl.DeleteChildren,
or rather wxTreeListItem::DeleteChildren.
wxTreeListCtrl::DeleteChildren invokes
wx.TreeListMainWindow::DeleteChildren:
void wxTreeListCtrl::DeleteChildren(const wxTreeItemId& item)
{ m_main_win->DeleteChildren(item); }
wxTreeListMainWindow::DeleteChildren in turn calls
wxTreeListItem::DeleteChildren:
void wxTreeListMainWindow::DeleteChildren (const wxTreeItemId& itemId) {
wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
m_dirty = true; // do this first so stuff below doesn't cause flicker
item->DeleteChildren (this);
}
Note how wxTreeListItem::DeleteChildren makes sure m_selectItem stays
valid, but never touches tree->m_curItem:
void wxTreeListItem::DeleteChildren (wxTreeListMainWindow *tree) {
size_t count = m_children.Count();
for (size_t n = 0; n < count; n++) {
wxTreeListItem *child = m_children[n];
if (tree) {
tree->SendDeleteEvent (child);
if (tree->m_selectItem == child) tree->m_selectItem =
(wxTreeListItem*)NULL;
}
child->DeleteChildren (tree);
delete child;
}
m_children.Empty();
}
If I next delete another item in the tree with wxTreeListCtrl::Delete,
wxTreeListMainWindow::Delete is invoked:
void wxTreeListCtrl::Delete(const wxTreeItemId& item)
{ m_main_win->Delete(item); }
wxTreeListMainWindow::Delete in turn calls wxTreeListItem::Delete,
which tries to check whether item is a descendant of m_curItem:
void wxTreeListMainWindow::Delete (const wxTreeItemId& itemId) {
....
if ( IsDescendantOf(item, m_curItem) )
{
......
But m_curItem may point to a deleted item with a crash as result.
Correct analysis?
Cheers, Frank