- Rework the {Insert,Delete}Column functions.
- Drawing optimizations when adding/removing columns. - More cleanups, and simplifications.
This commit is contained in:
parent
9842b19931
commit
25bf08267a
|
@ -162,7 +162,6 @@ typedef struct tagLISTVIEW_INFO
|
||||||
WNDPROC EditWndProc;
|
WNDPROC EditWndProc;
|
||||||
INT nEditLabelItem;
|
INT nEditLabelItem;
|
||||||
DWORD dwHoverTime;
|
DWORD dwHoverTime;
|
||||||
INT nColumnCount; /* the number of columns in this control */
|
|
||||||
|
|
||||||
DWORD lastKeyPressTimestamp;
|
DWORD lastKeyPressTimestamp;
|
||||||
WPARAM charCode;
|
WPARAM charCode;
|
||||||
|
@ -269,18 +268,14 @@ static INT LISTVIEW_HitTestItem(LISTVIEW_INFO *, LPLVHITTESTINFO, BOOL);
|
||||||
static void LISTVIEW_AlignLeft(LISTVIEW_INFO *);
|
static void LISTVIEW_AlignLeft(LISTVIEW_INFO *);
|
||||||
static void LISTVIEW_AlignTop(LISTVIEW_INFO *);
|
static void LISTVIEW_AlignTop(LISTVIEW_INFO *);
|
||||||
static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *, INT);
|
static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *, INT);
|
||||||
static void LISTVIEW_AddSelection(LISTVIEW_INFO *, INT);
|
|
||||||
static INT LISTVIEW_GetItemHeight(LISTVIEW_INFO *);
|
static INT LISTVIEW_GetItemHeight(LISTVIEW_INFO *);
|
||||||
static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *, INT, LPPOINT);
|
static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *, INT, LPPOINT);
|
||||||
static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *, INT, LPRECT);
|
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_GetItemWidth(LISTVIEW_INFO *);
|
||||||
static INT LISTVIEW_GetLabelWidth(LISTVIEW_INFO *, INT);
|
static INT LISTVIEW_GetLabelWidth(LISTVIEW_INFO *, INT);
|
||||||
static LRESULT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *, INT);
|
static LRESULT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *, INT);
|
||||||
static BOOL LISTVIEW_GetOrigin(LISTVIEW_INFO *, LPPOINT);
|
static BOOL LISTVIEW_GetOrigin(LISTVIEW_INFO *, LPPOINT);
|
||||||
static BOOL LISTVIEW_GetViewRect(LISTVIEW_INFO *, LPRECT);
|
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 void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *, INT);
|
||||||
static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *, LPLVITEMW, BOOL);
|
static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *, LPLVITEMW, BOOL);
|
||||||
static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *, INT, LONG, LONG);
|
static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *, INT, LONG, LONG);
|
||||||
|
@ -1496,7 +1491,6 @@ static BOOL LISTVIEW_GetItemMeasures(LISTVIEW_INFO *infoPtr, INT nItem,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*FIXME: should this be Label or FullText */
|
|
||||||
UnionRect(&Boundary, &Icon, &Label);
|
UnionRect(&Boundary, &Icon, &Label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1665,8 +1659,7 @@ static BOOL LISTVIEW_GetViewRect(LISTVIEW_INFO *infoPtr, LPRECT lprcView)
|
||||||
*lprcView = infoPtr->rcView;
|
*lprcView = infoPtr->rcView;
|
||||||
OffsetRect(lprcView, ptOrigin.x, ptOrigin.y);
|
OffsetRect(lprcView, ptOrigin.x, ptOrigin.y);
|
||||||
|
|
||||||
TRACE("(left=%d, top=%d, right=%d, bottom=%d)\n",
|
TRACE("lprcView=%s\n", debugrect(lprcView));
|
||||||
lprcView->left, lprcView->top, lprcView->right, lprcView->bottom);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2100,7 +2093,7 @@ static LRESULT LISTVIEW_RemoveAllSelections(LISTVIEW_INFO *infoPtr)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
sel = DPA_GetPtr(infoPtr->hdpaSelectionRanges,0);
|
sel = DPA_GetPtr(infoPtr->hdpaSelectionRanges, 0);
|
||||||
if (sel) LISTVIEW_RemoveSelectionRange(infoPtr, sel->lower, sel->upper);
|
if (sel) LISTVIEW_RemoveSelectionRange(infoPtr, sel->lower, sel->upper);
|
||||||
}
|
}
|
||||||
while (infoPtr->hdpaSelectionRanges->nItemCount > 0);
|
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:
|
* DESCRIPTION:
|
||||||
* Sets a single group selection.
|
* Sets a single group selection.
|
||||||
|
@ -2490,82 +2458,6 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, POINTS pt
|
||||||
return 0;
|
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]
|
* 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);
|
hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
|
||||||
if (!hdpaSubItems && hdpaSubItems != (HDPA)-1) return FALSE;
|
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;
|
if (!lpItem) return FALSE;
|
||||||
|
|
||||||
/* determine what fields will change */
|
/* determine what fields will change */
|
||||||
|
@ -3066,8 +2958,7 @@ static void LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT
|
||||||
INT textLeft;
|
INT textLeft;
|
||||||
INT nLabelWidth = 0;
|
INT nLabelWidth = 0;
|
||||||
|
|
||||||
TRACE("(hdc=%x, nItem=%d, nSubItem=%d)\n", hdc,
|
TRACE("(hdc=%x, nItem=%d, nSubItem=%d)\n", hdc, nItem, nSubItem);
|
||||||
nItem, nSubItem);
|
|
||||||
|
|
||||||
/* get information needed for drawing the item */
|
/* get information needed for drawing the item */
|
||||||
lvItem.mask = LVIF_TEXT;
|
lvItem.mask = LVIF_TEXT;
|
||||||
|
@ -3095,7 +2986,7 @@ static void LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set item colors */
|
/* set item colors */
|
||||||
if (ListView_GetItemState(infoPtr->hwndSelf,nItem,LVIS_SELECTED) && Selected)
|
if (LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED) && Selected)
|
||||||
{
|
{
|
||||||
if (infoPtr->bFocus)
|
if (infoPtr->bFocus)
|
||||||
{
|
{
|
||||||
|
@ -3124,9 +3015,8 @@ static void LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT
|
||||||
SetTextColor(hdc, infoPtr->clrText);
|
SetTextColor(hdc, infoPtr->clrText);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("drawing text %s, l=%d, t=%d, rect=(%d,%d)-(%d,%d)\n",
|
TRACE("drawing text %s, len=%d, rect=%s\n",
|
||||||
debugstr_w(lvItem.pszText), textLeft, rcItem.top,
|
debugstr_w(lvItem.pszText), textLeft, debugrect(&rcItem));
|
||||||
rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);
|
|
||||||
ExtTextOutW(hdc, textLeft, rcItem.top, textoutOptions,
|
ExtTextOutW(hdc, textLeft, rcItem.top, textoutOptions,
|
||||||
&rcItem, lvItem.pszText, lstrlenW(lvItem.pszText), NULL);
|
&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 */
|
/* cache column info */
|
||||||
nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
|
nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
|
||||||
infoPtr->nColumnCount = nColumnCount; /* update nColumnCount */
|
|
||||||
lprcCols = COMCTL32_Alloc(nColumnCount * sizeof(RECT));
|
lprcCols = COMCTL32_Alloc(nColumnCount * sizeof(RECT));
|
||||||
if (!lprcCols) return;
|
if (!lprcCols) return;
|
||||||
for (j = 0; j < nColumnCount; j++)
|
for (j = 0; j < nColumnCount; j++)
|
||||||
|
{
|
||||||
Header_GetItemRect(infoPtr->hwndHeader, j, &lprcCols[j]);
|
Header_GetItemRect(infoPtr->hwndHeader, j, &lprcCols[j]);
|
||||||
|
TRACE("lprcCols[%d]=%s\n", j, debugrect(&lprcCols[j]));
|
||||||
|
}
|
||||||
|
|
||||||
/* Get scroll info once before loop */
|
/* Get scroll info once before loop */
|
||||||
LISTVIEW_GetOrigin(infoPtr, &ptOrig);
|
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 */
|
/* get number of fully visible columns */
|
||||||
nColumnCount = nListWidth / nItemWidth;
|
nColumnCount = nListWidth / nItemWidth;
|
||||||
if (nListWidth % nItemWidth) nColumnCount++;
|
if (nListWidth % nItemWidth) nColumnCount++;
|
||||||
infoPtr->nColumnCount = nColumnCount;
|
|
||||||
nCountPerColumn = LISTVIEW_GetCountPerColumn(infoPtr);
|
nCountPerColumn = LISTVIEW_GetCountPerColumn(infoPtr);
|
||||||
nItem = ListView_GetTopIndex(infoPtr->hwndSelf);
|
nItem = ListView_GetTopIndex(infoPtr->hwndSelf);
|
||||||
TRACE("nColumnCount=%d, nCountPerColumn=%d, start item=%d\n",
|
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;
|
DWORD cditemmode = CDRF_DODEFAULT;
|
||||||
|
|
||||||
TRACE("\n");
|
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 */
|
/* nothing to draw, return here */
|
||||||
if(GETITEMCOUNT(infoPtr) == 0)
|
if(GETITEMCOUNT(infoPtr) == 0)
|
||||||
|
@ -4130,10 +4019,67 @@ static LRESULT LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr)
|
||||||
*/
|
*/
|
||||||
static BOOL LISTVIEW_DeleteColumn(LISTVIEW_INFO *infoPtr, INT nColumn)
|
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))
|
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 */
|
/* Need to reset the item width when deleting a column */
|
||||||
infoPtr->nItemWidth = LISTVIEW_GetItemWidth(infoPtr);
|
infoPtr->nItemWidth = LISTVIEW_GetItemWidth(infoPtr);
|
||||||
|
@ -4141,8 +4087,11 @@ static BOOL LISTVIEW_DeleteColumn(LISTVIEW_INFO *infoPtr, INT nColumn)
|
||||||
/* update scrollbar(s) */
|
/* update scrollbar(s) */
|
||||||
LISTVIEW_UpdateScroll(infoPtr);
|
LISTVIEW_UpdateScroll(infoPtr);
|
||||||
|
|
||||||
/* FIXME: invalidate only fromthe deleted column to the right */
|
/* scroll to cover the deleted column, and invalidate for redraw */
|
||||||
LISTVIEW_InvalidateList(infoPtr);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -4899,24 +4848,24 @@ static LRESULT LISTVIEW_GetColumnOrderArray(LISTVIEW_INFO *infoPtr, INT iCount,
|
||||||
*/
|
*/
|
||||||
static LRESULT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn)
|
static LRESULT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn)
|
||||||
{
|
{
|
||||||
UINT uView = LISTVIEW_GetType(infoPtr);
|
INT nColumnWidth = 0;
|
||||||
INT nColumnWidth = 0;
|
HDITEMW hdi;
|
||||||
HDITEMW hdi;
|
|
||||||
|
|
||||||
if (uView == LVS_LIST)
|
switch(LISTVIEW_GetType(infoPtr))
|
||||||
{
|
{
|
||||||
nColumnWidth = infoPtr->nItemWidth;
|
case LVS_LIST:
|
||||||
}
|
nColumnWidth = infoPtr->nItemWidth;
|
||||||
else if (uView == LVS_REPORT)
|
break;
|
||||||
{
|
case LVS_REPORT:
|
||||||
/* get column width from header */
|
hdi.mask = HDI_WIDTH;
|
||||||
ZeroMemory(&hdi, sizeof(hdi));
|
if (Header_GetItemW(infoPtr->hwndHeader, nColumn, &hdi))
|
||||||
hdi.mask = HDI_WIDTH;
|
nColumnWidth = hdi.cxy;
|
||||||
if (Header_GetItemW(infoPtr->hwndHeader, nColumn, &hdi))
|
break;
|
||||||
nColumnWidth = hdi.cxy;
|
default:
|
||||||
}
|
/* we don't have a 'column' in [SMALL]ICON mode */
|
||||||
|
}
|
||||||
|
|
||||||
return nColumnWidth;
|
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
|
static BOOL LISTVIEW_GetSubItemRect(LISTVIEW_INFO *infoPtr, INT nItem, INT nSubItem, INT flags, LPRECT lprc)
|
||||||
flags, LPRECT lprc)
|
|
||||||
{
|
{
|
||||||
UINT uView = LISTVIEW_GetType(infoPtr);
|
UINT uView = LISTVIEW_GetType(infoPtr);
|
||||||
INT count;
|
INT count;
|
||||||
|
@ -5475,7 +5423,7 @@ flags, LPRECT lprc)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int top = min(infoPtr->nColumnCount, nSubItem - 1);
|
int top = min(Header_GetItemCount(infoPtr->hwndHeader), nSubItem - 1);
|
||||||
|
|
||||||
LISTVIEW_GetItemRect(infoPtr,nItem,lprc);
|
LISTVIEW_GetItemRect(infoPtr,nItem,lprc);
|
||||||
for (count = 0; count < top; count++)
|
for (count = 0; count < top; count++)
|
||||||
|
@ -5964,9 +5912,10 @@ static INT LISTVIEW_SuperHitTestItem(LISTVIEW_INFO *infoPtr, LPLV_INTHIT lpInt,
|
||||||
set_subitem:
|
set_subitem:
|
||||||
if (subitem)
|
if (subitem)
|
||||||
{
|
{
|
||||||
|
INT nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
|
||||||
lpInt->ht.iSubItem = 0;
|
lpInt->ht.iSubItem = 0;
|
||||||
rcSubItem.right = rcSubItem.left;
|
rcSubItem.right = rcSubItem.left;
|
||||||
for (j = 0; j < infoPtr->nColumnCount; j++)
|
for (j = 0; j < nColumnCount; j++)
|
||||||
{
|
{
|
||||||
rcSubItem.left = rcSubItem.right;
|
rcSubItem.left = rcSubItem.right;
|
||||||
rcSubItem.right += LISTVIEW_GetColumnWidth(infoPtr, j);
|
rcSubItem.right += LISTVIEW_GetColumnWidth(infoPtr, j);
|
||||||
|
@ -6116,127 +6065,161 @@ static LRESULT LISTVIEW_SubItemHitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO l
|
||||||
static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
|
static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
|
||||||
LPLVCOLUMNW lpColumn, BOOL isW)
|
LPLVCOLUMNW lpColumn, BOOL isW)
|
||||||
{
|
{
|
||||||
INT nNewColumn = -1;
|
RECT rcOld, rcCol;
|
||||||
HDITEMW hdi;
|
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)
|
if (!lpColumn) return -1;
|
||||||
{
|
|
||||||
/* initialize memory */
|
|
||||||
ZeroMemory(&hdi, sizeof(hdi));
|
|
||||||
|
|
||||||
|
hdi.mask = hdi.fmt = 0;
|
||||||
if (lpColumn->mask & LVCF_FMT)
|
if (lpColumn->mask & LVCF_FMT)
|
||||||
{
|
{
|
||||||
/* format member is valid */
|
/* format member is valid */
|
||||||
hdi.mask |= HDI_FORMAT;
|
hdi.mask |= HDI_FORMAT;
|
||||||
|
|
||||||
/* set text alignment (leftmost column must be left-aligned) */
|
/* set text alignment (leftmost column must be left-aligned) */
|
||||||
if (nColumn == 0)
|
if (nColumn == 0 || lpColumn->fmt & LVCFMT_LEFT)
|
||||||
{
|
hdi.fmt |= HDF_LEFT;
|
||||||
hdi.fmt |= HDF_LEFT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (lpColumn->fmt & LVCFMT_LEFT)
|
|
||||||
{
|
|
||||||
hdi.fmt |= HDF_LEFT;
|
|
||||||
}
|
|
||||||
else if (lpColumn->fmt & LVCFMT_RIGHT)
|
else if (lpColumn->fmt & LVCFMT_RIGHT)
|
||||||
{
|
hdi.fmt |= HDF_RIGHT;
|
||||||
hdi.fmt |= HDF_RIGHT;
|
|
||||||
}
|
|
||||||
else if (lpColumn->fmt & LVCFMT_CENTER)
|
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)
|
||||||
{
|
{
|
||||||
hdi.fmt |= HDF_CENTER;
|
hdi.fmt |= HDF_IMAGE;
|
||||||
|
hdi.iImage = I_IMAGECALLBACK;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (lpColumn->fmt & LVCFMT_BITMAP_ON_RIGHT)
|
if (lpColumn->fmt & LVCFMT_IMAGE)
|
||||||
{
|
; /* FIXME: enable images for *(sub)items* this column */
|
||||||
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->mask & LVCF_WIDTH)
|
if (lpColumn->mask & LVCF_WIDTH)
|
||||||
{
|
{
|
||||||
hdi.mask |= HDI_WIDTH;
|
hdi.mask |= HDI_WIDTH;
|
||||||
if(lpColumn->cx == LVSCW_AUTOSIZE_USEHEADER)
|
if(lpColumn->cx == LVSCW_AUTOSIZE_USEHEADER)
|
||||||
{
|
{
|
||||||
/* make it fill the remainder of the controls width */
|
/* make it fill the remainder of the controls width */
|
||||||
HDITEMW hdit;
|
HDITEMW hdit;
|
||||||
RECT rcHeader;
|
RECT rcHeader;
|
||||||
INT item_index;
|
INT item_index;
|
||||||
|
|
||||||
ZeroMemory(&hdit, sizeof(hdit));
|
/* get the width of every item except the current one */
|
||||||
|
hdit.mask = HDI_WIDTH;
|
||||||
|
hdi.cxy = 0;
|
||||||
|
|
||||||
/* get the width of every item except the current one */
|
for(item_index = 0; item_index < (nColumn - 1); item_index++)
|
||||||
hdit.mask = HDI_WIDTH;
|
if (Header_GetItemW(infoPtr->hwndHeader, item_index, (LPARAM)(&hdit)))
|
||||||
hdi.cxy = 0;
|
hdi.cxy += hdit.cxy;
|
||||||
|
|
||||||
for(item_index = 0; item_index < (nColumn - 1); item_index++) {
|
/* retrieve the layout of the header */
|
||||||
Header_GetItemW(infoPtr->hwndHeader, item_index, (LPARAM)(&hdit));
|
GetClientRect(infoPtr->hwndSelf, &rcHeader);
|
||||||
hdi.cxy+=hdit.cxy;
|
TRACE("start cxy=%d rcHeader=%s\n", hdi.cxy, debugrect(&rcHeader));
|
||||||
|
|
||||||
|
hdi.cxy = (rcHeader.right - rcHeader.left) - hdi.cxy;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* retrieve the layout of the header */
|
hdi.cxy = lpColumn->cx;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpColumn->mask & LVCF_TEXT)
|
if (lpColumn->mask & LVCF_TEXT)
|
||||||
{
|
{
|
||||||
hdi.mask |= HDI_TEXT | HDI_FORMAT;
|
hdi.mask |= HDI_TEXT | HDI_FORMAT;
|
||||||
hdi.pszText = lpColumn->pszText;
|
hdi.fmt |= HDF_STRING;
|
||||||
hdi.cchTextMax = textlenT(lpColumn->pszText, isW);
|
hdi.pszText = lpColumn->pszText;
|
||||||
hdi.fmt |= HDF_STRING;
|
hdi.cchTextMax = textlenT(lpColumn->pszText, isW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpColumn->mask & LVCF_IMAGE)
|
if (lpColumn->mask & LVCF_IMAGE)
|
||||||
{
|
{
|
||||||
hdi.mask |= HDI_IMAGE;
|
hdi.mask |= HDI_IMAGE;
|
||||||
hdi.iImage = lpColumn->iImage;
|
hdi.iImage = lpColumn->iImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpColumn->mask & LVCF_ORDER)
|
if (lpColumn->mask & LVCF_ORDER)
|
||||||
{
|
{
|
||||||
hdi.mask |= HDI_ORDER;
|
hdi.mask |= HDI_ORDER;
|
||||||
hdi.iOrder = lpColumn->iOrder;
|
hdi.iOrder = lpColumn->iOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* insert item in header control */
|
/* insert item in header control */
|
||||||
nNewColumn = SendMessageW(infoPtr->hwndHeader,
|
nNewColumn = SendMessageW(infoPtr->hwndHeader,
|
||||||
isW ? HDM_INSERTITEMW : HDM_INSERTITEMA,
|
isW ? HDM_INSERTITEMW : HDM_INSERTITEMA,
|
||||||
(WPARAM)nColumn, (LPARAM)&hdi);
|
(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 */
|
/* Need to reset the item width when inserting a new column */
|
||||||
infoPtr->nItemWidth = LISTVIEW_GetItemWidth(infoPtr);
|
infoPtr->nItemWidth = LISTVIEW_GetItemWidth(infoPtr);
|
||||||
|
|
||||||
LISTVIEW_UpdateScroll(infoPtr);
|
LISTVIEW_UpdateScroll(infoPtr);
|
||||||
|
|
||||||
/* FIXME: invalidate from inserted column to right */
|
/* scroll to cover the deleted column, and invalidate for redraw */
|
||||||
LISTVIEW_InvalidateList(infoPtr);
|
rcOld = infoPtr->rcList;
|
||||||
}
|
rcOld.left = rcCol.left;
|
||||||
|
ScrollWindowEx(infoPtr->hwndSelf, rcCol.right - rcCol.left, 0,
|
||||||
return nNewColumn;
|
&rcOld, &rcOld, 0, 0, SW_ERASE | SW_INVALIDATE);
|
||||||
|
|
||||||
|
return nNewColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LISTVIEW_InsertCompare: callback routine for comparing pszText members of the LV_ITEMS
|
/* LISTVIEW_InsertCompare: callback routine for comparing pszText members of the LV_ITEMS
|
||||||
|
@ -7566,7 +7549,7 @@ static void scroll_list(LISTVIEW_INFO *infoPtr, INT dx, INT dy)
|
||||||
{
|
{
|
||||||
/* now we can scroll the list */
|
/* now we can scroll the list */
|
||||||
ScrollWindowEx(infoPtr->hwndSelf, dx, dy, &infoPtr->rcList,
|
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 we have focus, adjust rect */
|
||||||
if (infoPtr->bFocus && !IsRectEmpty(&infoPtr->rcFocus))
|
if (infoPtr->bFocus && !IsRectEmpty(&infoPtr->rcFocus))
|
||||||
OffsetRect(&infoPtr->rcFocus, dx, dy);
|
OffsetRect(&infoPtr->rcFocus, dx, dy);
|
||||||
|
@ -8041,7 +8024,17 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pt
|
||||||
if (bGroupSelect)
|
if (bGroupSelect)
|
||||||
LISTVIEW_AddGroupSelection(infoPtr, nItem);
|
LISTVIEW_AddGroupSelection(infoPtr, nItem);
|
||||||
else
|
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)
|
else if (wKey & MK_CONTROL)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue