- Rework the {Insert,Delete}Column functions.

- Drawing optimizations when adding/removing columns.
- More cleanups, and simplifications.
This commit is contained in:
Dimitrie O. Paun 2002-10-02 18:32:08 +00:00 committed by Alexandre Julliard
parent 9842b19931
commit 25bf08267a
1 changed files with 219 additions and 226 deletions

View File

@ -162,7 +162,6 @@ typedef struct tagLISTVIEW_INFO
WNDPROC EditWndProc;
INT nEditLabelItem;
DWORD dwHoverTime;
INT nColumnCount; /* the number of columns in this control */
DWORD lastKeyPressTimestamp;
WPARAM charCode;
@ -269,18 +268,14 @@ static INT LISTVIEW_HitTestItem(LISTVIEW_INFO *, LPLVHITTESTINFO, BOOL);
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 @@ static BOOL LISTVIEW_GetItemMeasures(LISTVIEW_INFO *infoPtr, INT nItem,
}
else
{
/*FIXME: should this be Label or FullText */
UnionRect(&Boundary, &Icon, &Label);
}
@ -1665,8 +1659,7 @@ static BOOL LISTVIEW_GetViewRect(LISTVIEW_INFO *infoPtr, LPRECT lprcView)
*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 @@ static LRESULT LISTVIEW_RemoveAllSelections(LISTVIEW_INFO *infoPtr)
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);
@ -2237,31 +2230,6 @@ static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
}
/***
* 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.
@ -2490,82 +2458,6 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, POINTS pt
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 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
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 @@ static void LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT
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 @@ static void LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT
}
/* 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 @@ static void LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT
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 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode
/* 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++)
{
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 @@ static void LISTVIEW_RefreshList(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode)
/* 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 @@ static void LISTVIEW_RefreshIcon(LISTVIEW_INFO *infoPtr, HDC hdc, BOOL bSmall, D
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 LRESULT LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr)
*/
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 @@ static BOOL LISTVIEW_DeleteColumn(LISTVIEW_INFO *infoPtr, INT nColumn)
/* 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,21 +4848,21 @@ static LRESULT LISTVIEW_GetColumnOrderArray(LISTVIEW_INFO *infoPtr, INT iCount,
*/
static LRESULT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn)
{
UINT uView = LISTVIEW_GetType(infoPtr);
INT nColumnWidth = 0;
HDITEMW hdi;
if (uView == LVS_LIST)
switch(LISTVIEW_GetType(infoPtr))
{
case LVS_LIST:
nColumnWidth = infoPtr->nItemWidth;
}
else if (uView == LVS_REPORT)
{
/* get column width from header */
ZeroMemory(&hdi, sizeof(hdi));
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;
@ -5456,8 +5405,7 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
}
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 @@ flags, LPRECT lprc)
}
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 @@ static INT LISTVIEW_SuperHitTestItem(LISTVIEW_INFO *infoPtr, LPLV_INTHIT lpInt,
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,58 +6065,39 @@ static LRESULT LISTVIEW_SubItemHitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO l
static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
LPLVCOLUMNW lpColumn, BOOL isW)
{
INT nNewColumn = -1;
RECT rcOld, rcCol;
INT nNewColumn;
HDITEMW hdi;
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;
/* set text alignment (leftmost column must be left-aligned) */
if (nColumn == 0)
{
if (nColumn == 0 || lpColumn->fmt & LVCFMT_LEFT)
hdi.fmt |= HDF_LEFT;
}
else
{
if (lpColumn->fmt & LVCFMT_LEFT)
{
hdi.fmt |= HDF_LEFT;
}
else if (lpColumn->fmt & LVCFMT_RIGHT)
{
hdi.fmt |= HDF_RIGHT;
}
else if (lpColumn->fmt & LVCFMT_CENTER)
{
hdi.fmt |= HDF_CENTER;
}
}
if (lpColumn->fmt & LVCFMT_BITMAP_ON_RIGHT)
{
hdi.fmt |= HDF_BITMAP_ON_RIGHT;
/* ??? */
}
if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES)
{
/* ??? */
}
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)
@ -6180,21 +6110,17 @@ static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
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;
for(item_index = 0; item_index < (nColumn - 1); item_index++) {
Header_GetItemW(infoPtr->hwndHeader, item_index, (LPARAM)(&hdit));
hdi.cxy+=hdit.cxy;
}
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);
/* GetWindowRect(infoPtr->hwndHeader, &rcHeader);*/
TRACE("start cxy=%d left=%d right=%d\n", hdi.cxy, rcHeader.left, rcHeader.right);
TRACE("start cxy=%d rcHeader=%s\n", hdi.cxy, debugrect(&rcHeader));
hdi.cxy = (rcHeader.right - rcHeader.left) - hdi.cxy;
}
@ -6205,9 +6131,9 @@ static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
if (lpColumn->mask & LVCF_TEXT)
{
hdi.mask |= HDI_TEXT | HDI_FORMAT;
hdi.fmt |= HDF_STRING;
hdi.pszText = lpColumn->pszText;
hdi.cchTextMax = textlenT(lpColumn->pszText, isW);
hdi.fmt |= HDF_STRING;
}
if (lpColumn->mask & LVCF_IMAGE)
@ -6226,15 +6152,72 @@ static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
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);
}
/* 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;
}
@ -7566,7 +7549,7 @@ static void scroll_list(LISTVIEW_INFO *infoPtr, INT dx, INT dy)
{
/* 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 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pt
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)
{