When items are inserted in a partially populated treeview, the first
visible item was not correctly updated.
The first visible item was sometimes used to calculate the location of
other items when it had been freed.
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index f574609..e11c848 100644
--- a/dlls/comctl32/treeview.c
+++ b/dlls/comctl32/treeview.c
@@ -988,6 +988,16 @@
COMCTL32_Free(item);
if (infoPtr->selectedItem == item)
infoPtr->selectedItem = NULL;
+ if (infoPtr->hotItem == item)
+ infoPtr->hotItem = NULL;
+ if (infoPtr->focusedItem == item)
+ infoPtr->focusedItem = NULL;
+ if (infoPtr->firstVisible == item)
+ infoPtr->firstVisible = NULL;
+ if (infoPtr->dropItem == item)
+ infoPtr->dropItem = NULL;
+ if (infoPtr->insertMarkItem == item)
+ infoPtr->insertMarkItem = NULL;
}
@@ -1216,9 +1226,12 @@
switch ((DWORD)insertAfter)
{
case (DWORD)TVI_FIRST:
- TREEVIEW_InsertBefore(newItem, parentItem->firstChild, parentItem);
- if (infoPtr->firstVisible == parentItem->firstChild)
- TREEVIEW_SetFirstVisible(infoPtr, newItem, TRUE);
+ {
+ TREEVIEW_ITEM *originalFirst = parentItem->firstChild;
+ TREEVIEW_InsertBefore(newItem, parentItem->firstChild, parentItem);
+ if (infoPtr->firstVisible == originalFirst)
+ TREEVIEW_SetFirstVisible(infoPtr, newItem, TRUE);
+ }
break;
case (DWORD)TVI_LAST:
@@ -1531,6 +1544,7 @@
newFirstVisible = wineItem->prevSibling;
else if (wineItem->parent != infoPtr->root)
newFirstVisible = wineItem->parent;
+ TREEVIEW_SetFirstVisible(infoPtr, NULL, TRUE);
}
else
newFirstVisible = infoPtr->firstVisible;
@@ -1564,8 +1578,8 @@
if (visible)
{
- TREEVIEW_RecalculateVisibleOrder(infoPtr, prev);
TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE);
+ TREEVIEW_RecalculateVisibleOrder(infoPtr, prev);
TREEVIEW_UpdateScrollBars(infoPtr);
TREEVIEW_Invalidate(infoPtr, NULL);
}