Listview U2
Dimitrie O. Paun
dpaun at rogers.com
Sat Oct 19 10:53:25 CDT 2002
ChangeLog
Unify {Insert,Set}ColumnT as much as possible
Fix a bunch of problems in SetColumnT.
--- dlls/comctl32/listview.c.U1 Sat Oct 19 03:26:03 2002
+++ dlls/comctl32/listview.c Sat Oct 19 11:46:45 2002
@@ -5631,189 +5631,6 @@
}
-/***
- * DESCRIPTION:
- * Inserts a new column.
- *
- * PARAMETER(S):
- * [I] infoPtr : valid pointer to the listview structure
- * [I] nColumn : column index
- * [I] lpColumn : column information
- * [I] isW : TRUE if lpColumn is Unicode, FALSE otherwise
- *
- * RETURN:
- * SUCCESS : new column index
- * FAILURE : -1
- */
-static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
- LPLVCOLUMNW lpColumn, BOOL isW)
-{
- COLUMN_INFO *lpColumnInfo = NULL;
- RECT rcCol;
- INT nNewColumn;
- HDITEMW hdi;
-
- TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW);
-
- 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 || 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)
- {
- hdi.fmt |= HDF_IMAGE;
- hdi.iImage = I_IMAGECALLBACK;
- }
- }
-
- if (lpColumn->mask & LVCF_WIDTH)
- {
- hdi.mask |= HDI_WIDTH;
- if(lpColumn->cx == LVSCW_AUTOSIZE_USEHEADER)
- {
- /* make it fill the remainder of the controls width */
- RECT rcHeader;
- INT item_index;
-
- for(item_index = 0; item_index < (nColumn - 1); item_index++)
- if (LISTVIEW_GetHeaderRect(infoPtr, item_index, &rcHeader))
- hdi.cxy += rcHeader.right - rcHeader.left;
-
- /* retrieve the layout of the header */
- GetClientRect(infoPtr->hwndSelf, &rcHeader);
- TRACE("start cxy=%d rcHeader=%s\n", hdi.cxy, debugrect(&rcHeader));
-
- hdi.cxy = (rcHeader.right - rcHeader.left) - hdi.cxy;
- }
- else
- hdi.cxy = lpColumn->cx;
- }
-
- 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);
- }
-
- if (lpColumn->mask & LVCF_IMAGE)
- {
- hdi.mask |= HDI_IMAGE;
- hdi.iImage = lpColumn->iImage;
- }
-
- if (lpColumn->mask & LVCF_ORDER)
- {
- 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;
-
- /* create our own column info */
- if (!(lpColumnInfo = COMCTL32_Alloc(sizeof(COLUMN_INFO)))) goto fail;
- if (DPA_InsertPtr(infoPtr->hdpaColumns, nNewColumn, lpColumnInfo) == -1) goto fail;
- if (!Header_GetItemRect(infoPtr->hwndHeader, nNewColumn, &rcCol)) goto fail;
- lpColumnInfo->rcHeader = rcCol;
- if (lpColumn->mask & LVCF_FMT)
- {
- if (nColumn == 0 || lpColumn->fmt & LVCFMT_LEFT) lpColumnInfo->align = DT_LEFT;
- else if (lpColumn->fmt & LVCFMT_RIGHT) lpColumnInfo->align = DT_RIGHT;
- else if (lpColumn->fmt & LVCFMT_CENTER) lpColumnInfo->align = DT_CENTER;
-
- if (lpColumn->fmt & LVCFMT_IMAGE) lpColumnInfo->hasImage = TRUE;
- }
- else
- {
- lpColumnInfo->align = DT_LEFT;
- lpColumnInfo->hasImage = (nColumn == 0);
- }
-
- /* now we have to actually adjust the data */
- if (!(infoPtr->dwStyle & LVS_OWNERDATA) && infoPtr->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->nItemCount);
- if (!lpNewItems) goto fail;
- for (i = 0; i < infoPtr->nItemCount; i++)
- if (!(lpNewItems[i] = COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM)))) break;
- if (i != infoPtr->nItemCount)
- {
- for(; i >=0; i--) COMCTL32_Free(lpNewItems[i]);
- COMCTL32_Free(lpNewItems);
- goto fail;
- }
- }
-
- for (nItem = 0; nItem < infoPtr->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);
- }
-
- /* make space for the new column */
- LISTVIEW_ScrollColumns(infoPtr, nNewColumn + 1, rcCol.right - rcCol.left);
-
- return nNewColumn;
-
-fail:
- if (nNewColumn != -1) SendMessageW(infoPtr->hwndHeader, HDM_DELETEITEM, nNewColumn, 0);
- if (lpColumnInfo)
- {
- DPA_DeletePtr(infoPtr->hdpaColumns, nNewColumn);
- COMCTL32_Free(lpColumnInfo);
- }
- return -1;
-}
-
/* LISTVIEW_InsertCompare: callback routine for comparing pszText members of the LV_ITEMS
in a LISTVIEW on insert. Passed to DPA_Sort in LISTVIEW_InsertItem.
This function should only be used for inserting items into a sorted list (LVM_INSERTITEM)
@@ -6066,6 +5883,205 @@
/* LISTVIEW_SetBkImage */
+/*** Helper for {Insert,Set}ColumnT *only* */
+static void column_fill_hditem(LISTVIEW_INFO *infoPtr, HDITEMW *lphdi, INT nColumn, LPLVCOLUMNW lpColumn, BOOL isW)
+{
+ if (lpColumn->mask & LVCF_FMT)
+ {
+ /* format member is valid */
+ lphdi->mask |= HDI_FORMAT;
+
+ /* set text alignment (leftmost column must be left-aligned) */
+ if (nColumn == 0 || lpColumn->fmt & LVCFMT_LEFT)
+ lphdi->fmt |= HDF_LEFT;
+ else if (lpColumn->fmt & LVCFMT_RIGHT)
+ lphdi->fmt |= HDF_RIGHT;
+ else if (lpColumn->fmt & LVCFMT_CENTER)
+ lphdi->fmt |= HDF_CENTER;
+
+ if (lpColumn->fmt & LVCFMT_BITMAP_ON_RIGHT)
+ lphdi->fmt |= HDF_BITMAP_ON_RIGHT;
+
+ if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES)
+ {
+ lphdi->fmt |= HDF_IMAGE;
+ lphdi->iImage = I_IMAGECALLBACK;
+ }
+ }
+
+ if (lpColumn->mask & LVCF_WIDTH)
+ {
+ lphdi->mask |= HDI_WIDTH;
+ if(lpColumn->cx == LVSCW_AUTOSIZE_USEHEADER)
+ {
+ /* make it fill the remainder of the controls width */
+ RECT rcHeader;
+ INT item_index;
+
+ for(item_index = 0; item_index < (nColumn - 1); item_index++)
+ if (LISTVIEW_GetHeaderRect(infoPtr, item_index, &rcHeader))
+ lphdi->cxy += rcHeader.right - rcHeader.left;
+
+ /* retrieve the layout of the header */
+ GetClientRect(infoPtr->hwndSelf, &rcHeader);
+ TRACE("start cxy=%d rcHeader=%s\n", lphdi->cxy, debugrect(&rcHeader));
+
+ lphdi->cxy = (rcHeader.right - rcHeader.left) - lphdi->cxy;
+ }
+ else
+ lphdi->cxy = lpColumn->cx;
+ }
+
+ if (lpColumn->mask & LVCF_TEXT)
+ {
+ lphdi->mask |= HDI_TEXT | HDI_FORMAT;
+ lphdi->fmt |= HDF_STRING;
+ lphdi->pszText = lpColumn->pszText;
+ lphdi->cchTextMax = textlenT(lpColumn->pszText, isW);
+ }
+
+ if (lpColumn->mask & LVCF_IMAGE)
+ {
+ lphdi->mask |= HDI_IMAGE;
+ lphdi->iImage = lpColumn->iImage;
+ }
+
+ if (lpColumn->mask & LVCF_ORDER)
+ {
+ lphdi->mask |= HDI_ORDER;
+ lphdi->iOrder = lpColumn->iOrder;
+ }
+}
+
+/*** Helper for {Insert,Set}ColumnT *only* */
+static BOOL column_fill_info(LISTVIEW_INFO *infoPtr, COLUMN_INFO *lpColumnInfo, INT nColumn, LPLVCOLUMNW lpColumn)
+{
+ RECT rcCol;
+
+ if (!Header_GetItemRect(infoPtr->hwndHeader, nColumn, &rcCol)) return FALSE;
+ lpColumnInfo->rcHeader = rcCol;
+ if (lpColumn->mask & LVCF_FMT)
+ {
+ if (nColumn == 0 || lpColumn->fmt & LVCFMT_LEFT) lpColumnInfo->align = DT_LEFT;
+ else if (lpColumn->fmt & LVCFMT_RIGHT) lpColumnInfo->align = DT_RIGHT;
+ else if (lpColumn->fmt & LVCFMT_CENTER) lpColumnInfo->align = DT_CENTER;
+
+ if (lpColumn->fmt & LVCFMT_IMAGE) lpColumnInfo->hasImage = TRUE;
+ }
+ else
+ {
+ lpColumnInfo->align = DT_LEFT;
+ lpColumnInfo->hasImage = (nColumn == 0);
+ }
+
+ return TRUE;
+}
+
+/***
+ * DESCRIPTION:
+ * Inserts a new column.
+ *
+ * PARAMETER(S):
+ * [I] infoPtr : valid pointer to the listview structure
+ * [I] nColumn : column index
+ * [I] lpColumn : column information
+ * [I] isW : TRUE if lpColumn is Unicode, FALSE otherwise
+ *
+ * RETURN:
+ * SUCCESS : new column index
+ * FAILURE : -1
+ */
+static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
+ LPLVCOLUMNW lpColumn, BOOL isW)
+{
+ COLUMN_INFO *lpColumnInfo;
+ INT nNewColumn;
+ HDITEMW hdi;
+
+ TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW);
+
+ if (!lpColumn) return -1;
+
+ ZeroMemory(&hdi, sizeof(HDITEMW));
+ column_fill_hditem(infoPtr, &hdi, nColumn, lpColumn, isW);
+
+ /* insert item in header control */
+ nNewColumn = SendMessageW(infoPtr->hwndHeader,
+ isW ? HDM_INSERTITEMW : HDM_INSERTITEMA,
+ (WPARAM)nColumn, (LPARAM)&hdi);
+ if (nNewColumn == -1) return -1;
+
+ /* create our own column info */
+ if (!(lpColumnInfo = COMCTL32_Alloc(sizeof(COLUMN_INFO)))) goto fail;
+ if (DPA_InsertPtr(infoPtr->hdpaColumns, nNewColumn, lpColumnInfo) == -1) goto fail;
+
+ if (!column_fill_info(infoPtr, lpColumnInfo, nNewColumn, lpColumn)) goto fail;
+
+ /* now we have to actually adjust the data */
+ if (!(infoPtr->dwStyle & LVS_OWNERDATA) && infoPtr->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->nItemCount);
+ if (!lpNewItems) goto fail;
+ for (i = 0; i < infoPtr->nItemCount; i++)
+ if (!(lpNewItems[i] = COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM)))) break;
+ if (i != infoPtr->nItemCount)
+ {
+ for(; i >=0; i--) COMCTL32_Free(lpNewItems[i]);
+ COMCTL32_Free(lpNewItems);
+ goto fail;
+ }
+ }
+
+ for (nItem = 0; nItem < infoPtr->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);
+ }
+
+ /* make space for the new column */
+ LISTVIEW_ScrollColumns(infoPtr, nNewColumn + 1, lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left);
+
+ return nNewColumn;
+
+fail:
+ if (nNewColumn != -1) SendMessageW(infoPtr->hwndHeader, HDM_DELETEITEM, nNewColumn, 0);
+ if (lpColumnInfo)
+ {
+ DPA_DeletePtr(infoPtr->hdpaColumns, nNewColumn);
+ COMCTL32_Free(lpColumnInfo);
+ }
+ return -1;
+}
+
/***
* DESCRIPTION:
* Sets the attributes of a header item.
@@ -6083,87 +6099,36 @@
static LRESULT LISTVIEW_SetColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
LPLVCOLUMNW lpColumn, BOOL isW)
{
- BOOL bResult = FALSE;
- HDITEMW hdi, hdiget;
+ COLUMN_INFO *lpColumnInfo;
+ HDITEMW hdi, hdiget;
+ BOOL bResult;
- if ((lpColumn != NULL) && (nColumn >= 0) && (nColumn < infoPtr->hdpaColumns->nItemCount))
- {
- /* initialize memory */
- ZeroMemory(&hdi, sizeof(hdi));
+ if (!lpColumn || nColumn < 0 || nColumn < infoPtr->hdpaColumns->nItemCount) return FALSE;
+ ZeroMemory(&hdi, sizeof(HDITEMW));
if (lpColumn->mask & LVCF_FMT)
{
- /* format member is valid */
- hdi.mask |= HDI_FORMAT;
+ /* format member is valid */
+ hdi.mask |= HDI_FORMAT;
- /* get current format first */
- hdiget.mask = HDI_FORMAT;
- if (Header_GetItemW(infoPtr->hwndHeader, nColumn, &hdiget))
+ /* get current format first */
+ hdiget.mask = HDI_FORMAT;
+ if (Header_GetItemW(infoPtr->hwndHeader, nColumn, &hdiget))
/* preserve HDF_STRING if present */
hdi.fmt = hdiget.fmt & HDF_STRING;
-
- /* 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;
- 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)
- hdi.fmt |= HDF_IMAGE;
-
- if (lpColumn->fmt & LVCFMT_IMAGE)
- {
- hdi.fmt |= HDF_IMAGE;
- hdi.iImage = I_IMAGECALLBACK;
- }
}
- if (lpColumn->mask & LVCF_WIDTH)
- {
- hdi.mask |= HDI_WIDTH;
- hdi.cxy = lpColumn->cx;
- }
+ if (!(lpColumnInfo = DPA_GetPtr(infoPtr->hdpaColumns, nColumn))) return FALSE;
- 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;
- }
-
- if (lpColumn->mask & LVCF_IMAGE)
- {
- hdi.mask |= HDI_IMAGE;
- hdi.iImage = lpColumn->iImage;
- }
-
- if (lpColumn->mask & LVCF_ORDER)
- {
- hdi.mask |= HDI_ORDER;
- hdi.iOrder = lpColumn->iOrder;
- }
+ column_fill_hditem(infoPtr, &hdi, nColumn, lpColumn, isW);
/* set header item attributes */
- if (isW)
- bResult = Header_SetItemW(infoPtr->hwndHeader, nColumn, &hdi);
- else
- bResult = Header_SetItemA(infoPtr->hwndHeader, nColumn, &hdi);
- }
+ bResult = SendMessageW(infoPtr->hwndHeader, isW ? HDM_SETITEMW : HDM_SETITEMA, (WPARAM)nColumn, (LPARAM)&hdi);
+ if (!bResult) return FALSE;
- return bResult;
+ if (!column_fill_info(infoPtr, lpColumnInfo, nColumn, lpColumn)) return FALSE;
+
+ return TRUE;
}
/***
More information about the wine-patches
mailing list