Listview updates (J0)
Dimitrie O. Paun
dpaun at rogers.com
Tue Oct 1 19:45:53 CDT 2002
This one reworks the {Insert,Delete}Column code.
The InsertColumn still doesn't work properly due to
a bug in Header control. This is not a step back,
as both were badly broken before.
ChangeLog
-- Rework the {Insert,Delete}Column functions
-- Drawing optimizations when adding/removing columns
-- More cleanups, and simplifications.
Index: dlls/comctl32/listview.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/listview.c,v
retrieving revision 1.158
diff -u -r1.158 listview.c
--- dlls/comctl32/listview.c 1 Oct 2002 18:06:15 -0000 1.158
+++ dlls/comctl32/listview.c 2 Oct 2002 00:41:08 -0000
@@ -162,7 +162,6 @@
WNDPROC EditWndProc;
INT nEditLabelItem;
DWORD dwHoverTime;
- INT nColumnCount; /* the number of columns in this control */
DWORD lastKeyPressTimestamp;
WPARAM charCode;
@@ -269,18 +268,14 @@
static void LISTVIEW_AlignLeft(LISTVIEW_INFO *);
static void LISTVIEW_AlignTop(LISTVIEW_INFO *);
static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *, INT);
-static void LISTVIEW_AddSelection(LISTVIEW_INFO *, INT);
static INT LISTVIEW_GetItemHeight(LISTVIEW_INFO *);
static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *, INT, LPPOINT);
static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *, INT, LPRECT);
-static BOOL LISTVIEW_GetSubItemRect(LISTVIEW_INFO *, INT, INT, INT, LPRECT);
static INT LISTVIEW_GetItemWidth(LISTVIEW_INFO *);
static INT LISTVIEW_GetLabelWidth(LISTVIEW_INFO *, INT);
static LRESULT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *, INT);
static BOOL LISTVIEW_GetOrigin(LISTVIEW_INFO *, LPPOINT);
static BOOL LISTVIEW_GetViewRect(LISTVIEW_INFO *, LPRECT);
-static BOOL LISTVIEW_RemoveColumn(HDPA, INT);
-static BOOL LISTVIEW_RemoveSubItem(HDPA, INT);
static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *, INT);
static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *, LPLVITEMW, BOOL);
static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *, INT, LONG, LONG);
@@ -1496,7 +1491,6 @@
}
else
{
- /*FIXME: should this be Label or FullText */
UnionRect(&Boundary, &Icon, &Label);
}
@@ -1665,8 +1659,7 @@
*lprcView = infoPtr->rcView;
OffsetRect(lprcView, ptOrigin.x, ptOrigin.y);
- TRACE("(left=%d, top=%d, right=%d, bottom=%d)\n",
- lprcView->left, lprcView->top, lprcView->right, lprcView->bottom);
+ TRACE("lprcView=%s\n", debugrect(lprcView));
return TRUE;
}
@@ -2100,7 +2093,7 @@
do
{
- sel = DPA_GetPtr(infoPtr->hdpaSelectionRanges,0);
+ sel = DPA_GetPtr(infoPtr->hdpaSelectionRanges, 0);
if (sel) LISTVIEW_RemoveSelectionRange(infoPtr, sel->lower, sel->upper);
}
while (infoPtr->hdpaSelectionRanges->nItemCount > 0);
@@ -2239,31 +2232,6 @@
/***
* DESCRIPTION:
- * Adds a single selection.
- *
- * PARAMETER(S):
- * [I] infoPtr : valid pointer to the listview structure
- * [I] INT : item index
- *
- * RETURN:
- * None
- */
-static void LISTVIEW_AddSelection(LISTVIEW_INFO *infoPtr, INT nItem)
-{
- LVITEMW item;
-
- item.state = LVIS_SELECTED;
- item.stateMask = LVIS_SELECTED;
-
- LISTVIEW_SetItemState(infoPtr,nItem,&item);
-
- LISTVIEW_SetItemFocus(infoPtr, nItem);
- infoPtr->nSelectionMark = nItem;
-}
-
-
-/***
- * DESCRIPTION:
* Sets a single group selection.
*
* PARAMETER(S):
@@ -2490,82 +2458,6 @@
return 0;
}
-/***
- * DESCRIPTION:
- * Removes a column.
- *
- * PARAMETER(S):
- * [IO] HDPA : dynamic pointer array handle
- * [I] INT : column index (subitem index)
- *
- * RETURN:
- * SUCCCESS : TRUE
- * FAILURE : FALSE
- */
-static BOOL LISTVIEW_RemoveColumn(HDPA hdpaItems, INT nSubItem)
-{
- BOOL bResult = TRUE;
- HDPA hdpaSubItems;
- INT i;
-
- for (i = 0; i < hdpaItems->nItemCount; i++)
- {
- hdpaSubItems = (HDPA)DPA_GetPtr(hdpaItems, i);
- if (hdpaSubItems != NULL)
- {
- if (!LISTVIEW_RemoveSubItem(hdpaSubItems, nSubItem))
- {
- bResult = FALSE;
- }
- }
- }
-
- return bResult;
-}
-
-/***
- * DESCRIPTION:
- * Removes a subitem at a given position.
- *
- * PARAMETER(S):
- * [IO] HDPA : dynamic pointer array handle
- * [I] INT : subitem index
- *
- * RETURN:
- * SUCCCESS : TRUE
- * FAILURE : FALSE
- */
-static BOOL LISTVIEW_RemoveSubItem(HDPA hdpaSubItems, INT nSubItem)
-{
- LISTVIEW_SUBITEM *lpSubItem;
- INT i;
-
- for (i = 1; i < hdpaSubItems->nItemCount; i++)
- {
- lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
- if (lpSubItem != NULL)
- {
- if (lpSubItem->iSubItem == nSubItem)
- {
- /* free string */
- if (is_textW(lpSubItem->hdr.pszText))
- COMCTL32_Free(lpSubItem->hdr.pszText);
-
- /* free item */
- COMCTL32_Free(lpSubItem);
-
- /* free dpa memory */
- if (DPA_DeletePtr(hdpaSubItems, i) == NULL)
- return FALSE;
- }
- else if (lpSubItem->iSubItem > nSubItem)
- return TRUE;
- }
- }
-
- return TRUE;
-}
-
/***
* DESCRIPTION: [INTERNAL]
@@ -2743,7 +2635,7 @@
hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
if (!hdpaSubItems && hdpaSubItems != (HDPA)-1) return FALSE;
- lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, lpLVItem->iSubItem);
+ lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
if (!lpItem) return FALSE;
/* determine what fields will change */
@@ -3066,8 +2958,7 @@
INT textLeft;
INT nLabelWidth = 0;
- TRACE("(hdc=%x, nItem=%d, nSubItem=%d)\n", hdc,
- nItem, nSubItem);
+ TRACE("(hdc=%x, nItem=%d, nSubItem=%d)\n", hdc, nItem, nSubItem);
/* get information needed for drawing the item */
lvItem.mask = LVIF_TEXT;
@@ -3095,7 +2986,7 @@
}
/* set item colors */
- if (ListView_GetItemState(infoPtr->hwndSelf,nItem,LVIS_SELECTED) && Selected)
+ if (LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED) && Selected)
{
if (infoPtr->bFocus)
{
@@ -3124,9 +3015,8 @@
SetTextColor(hdc, infoPtr->clrText);
}
- TRACE("drawing text %s, l=%d, t=%d, rect=(%d,%d)-(%d,%d)\n",
- debugstr_w(lvItem.pszText), textLeft, rcItem.top,
- rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);
+ TRACE("drawing text %s, len=%d, rect=%s\n",
+ debugstr_w(lvItem.pszText), textLeft, debugrect(&rcItem));
ExtTextOutW(hdc, textLeft, rcItem.top, textoutOptions,
&rcItem, lvItem.pszText, lstrlenW(lvItem.pszText), NULL);
@@ -3558,11 +3448,13 @@
/* cache column info */
nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
- infoPtr->nColumnCount = nColumnCount; /* update nColumnCount */
lprcCols = COMCTL32_Alloc(nColumnCount * sizeof(RECT));
if (!lprcCols) return;
- for (j = 0; j < nColumnCount; j++)
+ for (j = 0; j < nColumnCount; j++)
+ {
Header_GetItemRect(infoPtr->hwndHeader, j, &lprcCols[j]);
+ TRACE("lprcCols[%d]=%s\n", j, debugrect(&lprcCols[j]));
+ }
/* Get scroll info once before loop */
LISTVIEW_GetOrigin(infoPtr, &ptOrig);
@@ -3685,7 +3577,6 @@
/* get number of fully visible columns */
nColumnCount = nListWidth / nItemWidth;
if (nListWidth % nItemWidth) nColumnCount++;
- infoPtr->nColumnCount = nColumnCount;
nCountPerColumn = LISTVIEW_GetCountPerColumn(infoPtr);
nItem = ListView_GetTopIndex(infoPtr->hwndSelf);
TRACE("nColumnCount=%d, nCountPerColumn=%d, start item=%d\n",
@@ -3741,8 +3632,6 @@
DWORD cditemmode = CDRF_DODEFAULT;
TRACE("\n");
- infoPtr->nColumnCount = 1; /* set this to an arbitrary value to prevent */
- /* DrawItem from erasing the incorrect background area */
/* nothing to draw, return here */
if(GETITEMCOUNT(infoPtr) == 0)
@@ -4130,10 +4019,67 @@
*/
static BOOL LISTVIEW_DeleteColumn(LISTVIEW_INFO *infoPtr, INT nColumn)
{
- if (!Header_DeleteItem(infoPtr->hwndHeader, nColumn)) return FALSE;
+ UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
+ RECT rcCol, rcOld;
+
+ TRACE("nColumn=%d\n", nColumn);
+
+ if (nColumn <= 0) return FALSE;
+
+ if (uView == LVS_REPORT)
+ {
+ if (!Header_GetItemRect(infoPtr->hwndHeader, nColumn, &rcCol))
+ return FALSE;
+
+ if (!Header_DeleteItem(infoPtr->hwndHeader, nColumn))
+ return FALSE;
+ }
if (!(infoPtr->dwStyle & LVS_OWNERDATA))
- LISTVIEW_RemoveColumn(infoPtr->hdpaItems, nColumn);
+ {
+ LISTVIEW_SUBITEM *lpSubItem, *lpDelItem;
+ HDPA hdpaSubItems;
+ INT nItem, nSubItem, i;
+
+ for (nItem = 0; nItem < infoPtr->hdpaItems->nItemCount; nItem++)
+ {
+ hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
+ if (!hdpaSubItems) continue;
+ nSubItem = 0;
+ lpDelItem = 0;
+ for (i = 1; i < hdpaSubItems->nItemCount; i++)
+ {
+ lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
+ if (!lpSubItem) break;
+ if (lpSubItem->iSubItem == nColumn)
+ {
+ nSubItem = i;
+ lpDelItem = lpSubItem;
+ }
+ else if (lpSubItem->iSubItem > nColumn)
+ {
+ lpSubItem->iSubItem--;
+ }
+ }
+
+ /* if we found our subitem, zapp it */
+ if (nSubItem > 0)
+ {
+ /* free string */
+ if (is_textW(lpDelItem->hdr.pszText))
+ COMCTL32_Free(lpDelItem->hdr.pszText);
+
+ /* free item */
+ COMCTL32_Free(lpDelItem);
+
+ /* free dpa memory */
+ DPA_DeletePtr(hdpaSubItems, nSubItem);
+ }
+ }
+ }
+
+ /* we need to worry about display issues in report mode only */
+ if (uView != LVS_REPORT) return TRUE;
/* Need to reset the item width when deleting a column */
infoPtr->nItemWidth = LISTVIEW_GetItemWidth(infoPtr);
@@ -4141,8 +4087,11 @@
/* update scrollbar(s) */
LISTVIEW_UpdateScroll(infoPtr);
- /* FIXME: invalidate only fromthe deleted column to the right */
- LISTVIEW_InvalidateList(infoPtr);
+ /* scroll to cover the deleted column, and invalidate for redraw */
+ rcOld = infoPtr->rcList;
+ rcOld.left = rcCol.left;
+ ScrollWindowEx(infoPtr->hwndSelf, -(rcCol.right - rcCol.left), 0,
+ &rcOld, &rcOld, 0, 0, SW_ERASE | SW_INVALIDATE);
return TRUE;
}
@@ -4899,24 +4848,24 @@
*/
static LRESULT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn)
{
- UINT uView = LISTVIEW_GetType(infoPtr);
- INT nColumnWidth = 0;
- HDITEMW hdi;
+ INT nColumnWidth = 0;
+ HDITEMW hdi;
- if (uView == LVS_LIST)
- {
- nColumnWidth = infoPtr->nItemWidth;
- }
- else if (uView == LVS_REPORT)
- {
- /* get column width from header */
- ZeroMemory(&hdi, sizeof(hdi));
- hdi.mask = HDI_WIDTH;
- if (Header_GetItemW(infoPtr->hwndHeader, nColumn, &hdi))
- nColumnWidth = hdi.cxy;
- }
+ switch(LISTVIEW_GetType(infoPtr))
+ {
+ case LVS_LIST:
+ nColumnWidth = infoPtr->nItemWidth;
+ break;
+ case LVS_REPORT:
+ hdi.mask = HDI_WIDTH;
+ if (Header_GetItemW(infoPtr->hwndHeader, nColumn, &hdi))
+ nColumnWidth = hdi.cxy;
+ break;
+ default:
+ /* we don't have a 'column' in [SMALL]ICON mode */
+ }
- return nColumnWidth;
+ return nColumnWidth;
}
/***
@@ -5456,8 +5405,7 @@
}
-static BOOL LISTVIEW_GetSubItemRect(LISTVIEW_INFO *infoPtr, INT nItem, INT nSubItem, INT
-flags, LPRECT lprc)
+static BOOL LISTVIEW_GetSubItemRect(LISTVIEW_INFO *infoPtr, INT nItem, INT nSubItem, INT flags, LPRECT lprc)
{
UINT uView = LISTVIEW_GetType(infoPtr);
INT count;
@@ -5475,7 +5423,7 @@
}
else
{
- int top = min(infoPtr->nColumnCount, nSubItem - 1);
+ int top = min(Header_GetItemCount(infoPtr->hwndHeader), nSubItem - 1);
LISTVIEW_GetItemRect(infoPtr,nItem,lprc);
for (count = 0; count < top; count++)
@@ -5964,9 +5912,10 @@
set_subitem:
if (subitem)
{
+ INT nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
lpInt->ht.iSubItem = 0;
rcSubItem.right = rcSubItem.left;
- for (j = 0; j < infoPtr->nColumnCount; j++)
+ for (j = 0; j < nColumnCount; j++)
{
rcSubItem.left = rcSubItem.right;
rcSubItem.right += LISTVIEW_GetColumnWidth(infoPtr, j);
@@ -6116,127 +6065,161 @@
static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
LPLVCOLUMNW lpColumn, BOOL isW)
{
- INT nNewColumn = -1;
- HDITEMW hdi;
+ RECT rcOld, rcCol;
+ INT nNewColumn;
+ HDITEMW hdi;
- TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW);
+ TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW);
- if (lpColumn != NULL)
- {
- /* initialize memory */
- ZeroMemory(&hdi, sizeof(hdi));
+ if (!lpColumn) return -1;
+ hdi.mask = hdi.fmt = 0;
if (lpColumn->mask & LVCF_FMT)
{
- /* format member is valid */
- hdi.mask |= HDI_FORMAT;
+ /* format member is valid */
+ hdi.mask |= HDI_FORMAT;
- /* set text alignment (leftmost column must be left-aligned) */
- if (nColumn == 0)
- {
- hdi.fmt |= HDF_LEFT;
- }
- else
- {
- if (lpColumn->fmt & LVCFMT_LEFT)
- {
- hdi.fmt |= HDF_LEFT;
- }
+ /* set text alignment (leftmost column must be left-aligned) */
+ if (nColumn == 0 || lpColumn->fmt & LVCFMT_LEFT)
+ hdi.fmt |= HDF_LEFT;
else if (lpColumn->fmt & LVCFMT_RIGHT)
- {
- hdi.fmt |= HDF_RIGHT;
- }
+ hdi.fmt |= HDF_RIGHT;
else if (lpColumn->fmt & LVCFMT_CENTER)
- {
- hdi.fmt |= HDF_CENTER;
- }
- }
+ hdi.fmt |= HDF_CENTER;
- if (lpColumn->fmt & LVCFMT_BITMAP_ON_RIGHT)
- {
- hdi.fmt |= HDF_BITMAP_ON_RIGHT;
- /* ??? */
- }
+ if (lpColumn->fmt & LVCFMT_BITMAP_ON_RIGHT)
+ hdi.fmt |= HDF_BITMAP_ON_RIGHT;
- if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES)
- {
- /* ??? */
- }
+ if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES)
+ {
+ hdi.fmt |= HDF_IMAGE;
+ hdi.iImage = I_IMAGECALLBACK;
+ }
- if (lpColumn->fmt & LVCFMT_IMAGE)
- {
- hdi.fmt |= HDF_IMAGE;
- hdi.iImage = I_IMAGECALLBACK;
- }
+ if (lpColumn->fmt & LVCFMT_IMAGE)
+ ; /* FIXME: enable images for *(sub)items* this column */
}
if (lpColumn->mask & LVCF_WIDTH)
{
- hdi.mask |= HDI_WIDTH;
- if(lpColumn->cx == LVSCW_AUTOSIZE_USEHEADER)
- {
- /* make it fill the remainder of the controls width */
- HDITEMW hdit;
- RECT rcHeader;
- INT item_index;
-
- ZeroMemory(&hdit, sizeof(hdit));
-
- /* get the width of every item except the current one */
- hdit.mask = HDI_WIDTH;
- hdi.cxy = 0;
+ hdi.mask |= HDI_WIDTH;
+ if(lpColumn->cx == LVSCW_AUTOSIZE_USEHEADER)
+ {
+ /* make it fill the remainder of the controls width */
+ HDITEMW hdit;
+ RECT rcHeader;
+ INT item_index;
+
+ /* get the width of every item except the current one */
+ hdit.mask = HDI_WIDTH;
+ hdi.cxy = 0;
+
+ for(item_index = 0; item_index < (nColumn - 1); item_index++)
+ if (Header_GetItemW(infoPtr->hwndHeader, item_index, (LPARAM)(&hdit)))
+ hdi.cxy += hdit.cxy;
+
+ /* retrieve the layout of the header */
+ GetClientRect(infoPtr->hwndSelf, &rcHeader);
+ TRACE("start cxy=%d rcHeader=%s\n", hdi.cxy, debugrect(&rcHeader));
- for(item_index = 0; item_index < (nColumn - 1); item_index++) {
- Header_GetItemW(infoPtr->hwndHeader, item_index, (LPARAM)(&hdit));
- hdi.cxy+=hdit.cxy;
+ hdi.cxy = (rcHeader.right - rcHeader.left) - hdi.cxy;
}
-
- /* retrieve the layout of the header */
- GetClientRect(infoPtr->hwndSelf, &rcHeader);
-/* GetWindowRect(infoPtr->hwndHeader, &rcHeader);*/
- TRACE("start cxy=%d left=%d right=%d\n", hdi.cxy, rcHeader.left, rcHeader.right);
-
- hdi.cxy = (rcHeader.right - rcHeader.left) - hdi.cxy;
- }
- else
- hdi.cxy = lpColumn->cx;
+ else
+ hdi.cxy = lpColumn->cx;
}
if (lpColumn->mask & LVCF_TEXT)
{
- hdi.mask |= HDI_TEXT | HDI_FORMAT;
- hdi.pszText = lpColumn->pszText;
- hdi.cchTextMax = textlenT(lpColumn->pszText, isW);
- hdi.fmt |= HDF_STRING;
+ hdi.mask |= HDI_TEXT | HDI_FORMAT;
+ hdi.fmt |= HDF_STRING;
+ hdi.pszText = lpColumn->pszText;
+ hdi.cchTextMax = textlenT(lpColumn->pszText, isW);
}
if (lpColumn->mask & LVCF_IMAGE)
{
- hdi.mask |= HDI_IMAGE;
- hdi.iImage = lpColumn->iImage;
+ hdi.mask |= HDI_IMAGE;
+ hdi.iImage = lpColumn->iImage;
}
if (lpColumn->mask & LVCF_ORDER)
{
- hdi.mask |= HDI_ORDER;
- hdi.iOrder = lpColumn->iOrder;
+ hdi.mask |= HDI_ORDER;
+ hdi.iOrder = lpColumn->iOrder;
}
/* insert item in header control */
nNewColumn = SendMessageW(infoPtr->hwndHeader,
isW ? HDM_INSERTITEMW : HDM_INSERTITEMA,
(WPARAM)nColumn, (LPARAM)&hdi);
+ if (nNewColumn == -1) return -1;
+ if (!Header_GetItemRect(infoPtr->hwndHeader, nNewColumn, &rcCol)) return -1;
+
+ /* now we have to actually adjust the data */
+ if (!(infoPtr->dwStyle & LVS_OWNERDATA) && infoPtr->hdpaItems->nItemCount > 0)
+ {
+ LISTVIEW_SUBITEM *lpSubItem, *lpMainItem, **lpNewItems = 0;
+ HDPA hdpaSubItems;
+ INT nItem, i;
+
+ /* preallocate memory, so we can fail gracefully */
+ if (nNewColumn == 0)
+ {
+ lpNewItems = COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM *) * infoPtr->hdpaItems->nItemCount);
+ if (!lpNewItems) return -1;
+ for (i = 0; i < infoPtr->hdpaItems->nItemCount; i++)
+ if (!(lpNewItems[i] = COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM)))) break;
+ if (i != infoPtr->hdpaItems->nItemCount)
+ {
+ for(; i >=0; i--) COMCTL32_Free(lpNewItems[i]);
+ COMCTL32_Free(lpNewItems);
+ return -1;
+ }
+ }
+
+ for (nItem = 0; nItem < infoPtr->hdpaItems->nItemCount; nItem++)
+ {
+ hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
+ if (!hdpaSubItems) continue;
+ for (i = 1; i < hdpaSubItems->nItemCount; i++)
+ {
+ lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
+ if (!lpSubItem) break;
+ if (lpSubItem->iSubItem >= nNewColumn)
+ lpSubItem->iSubItem++;
+ }
+
+ /* if we found our subitem, zapp it */
+ if (nNewColumn == 0)
+ {
+ lpMainItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, 0);
+ lpSubItem = lpNewItems[nItem];
+ lpSubItem->hdr = lpMainItem->hdr;
+ lpSubItem->iSubItem = 1;
+ ZeroMemory(&lpMainItem->hdr, sizeof(lpMainItem->hdr));
+ lpMainItem->iSubItem = 0;
+ DPA_InsertPtr(hdpaSubItems, 1, lpSubItem);
+ }
+ }
+ COMCTL32_Free(lpNewItems);
+ }
+
+ /* we don't have to worry abiut display issues in non-report mode */
+ if ((infoPtr->dwStyle & LVS_TYPEMASK) != LVS_REPORT) return nNewColumn;
+
/* Need to reset the item width when inserting a new column */
infoPtr->nItemWidth = LISTVIEW_GetItemWidth(infoPtr);
LISTVIEW_UpdateScroll(infoPtr);
- /* FIXME: invalidate from inserted column to right */
- LISTVIEW_InvalidateList(infoPtr);
- }
-
- return nNewColumn;
+ /* scroll to cover the deleted column, and invalidate for redraw */
+ rcOld = infoPtr->rcList;
+ rcOld.left = rcCol.left;
+ ScrollWindowEx(infoPtr->hwndSelf, rcCol.right - rcCol.left, 0,
+ &rcOld, &rcOld, 0, 0, SW_ERASE | SW_INVALIDATE);
+
+ return nNewColumn;
}
/* LISTVIEW_InsertCompare: callback routine for comparing pszText members of the LV_ITEMS
@@ -7566,7 +7549,7 @@
{
/* now we can scroll the list */
ScrollWindowEx(infoPtr->hwndSelf, dx, dy, &infoPtr->rcList,
- &infoPtr->rcList, 0, 0, SW_INVALIDATE);
+ &infoPtr->rcList, 0, 0, SW_ERASE | SW_INVALIDATE);
/* if we have focus, adjust rect */
if (infoPtr->bFocus && !IsRectEmpty(&infoPtr->rcFocus))
OffsetRect(&infoPtr->rcFocus, dx, dy);
@@ -8041,7 +8024,17 @@
if (bGroupSelect)
LISTVIEW_AddGroupSelection(infoPtr, nItem);
else
- LISTVIEW_AddSelection(infoPtr, nItem);
+ {
+ LVITEMW item;
+
+ item.state = LVIS_SELECTED;
+ item.stateMask = LVIS_SELECTED;
+
+ LISTVIEW_SetItemState(infoPtr,nItem,&item);
+
+ LISTVIEW_SetItemFocus(infoPtr, nItem);
+ infoPtr->nSelectionMark = nItem;
+ }
}
else if (wKey & MK_CONTROL)
{
More information about the wine-patches
mailing list