Listview V3
Dimitrie O. Paun
dpaun at rogers.com
Sun Oct 20 09:46:08 CDT 2002
This one completes the column related code rewrite.
ChangeLog
SetColumnWidth rewrite: simpler, cleaner code. Bugs squashed.
--- dlls/comctl32/listview.c.V2 Sun Oct 20 03:56:28 2002
+++ dlls/comctl32/listview.c Sun Oct 20 10:44:18 2002
@@ -6106,32 +6106,21 @@
*
* PARAMETERS:
* [I] infoPtr : valid pointer to the listview structure
- * [I] iCol : column index
+ * [I] nColumn : column index
* [I] cx : column width
*
* RETURN:
* SUCCESS : TRUE
* FAILURE : FALSE
*/
-static BOOL LISTVIEW_SetColumnWidth(LISTVIEW_INFO *infoPtr, INT iCol, INT cx)
+static BOOL LISTVIEW_SetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn, INT cx)
{
- HDITEMW hdi;
- LRESULT lret;
- LONG lStyle = infoPtr->dwStyle;
- UINT uView = lStyle & LVS_TYPEMASK;
- HDC hdc;
- HFONT header_font;
- HFONT old_font;
- SIZE size;
- WCHAR text_buffer[DISP_TEXT_SIZE];
- INT header_item_count;
- INT item_index;
- INT nLabelWidth;
- RECT rcHeader;
- LVITEMW lvItem;
+ UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
WCHAR szDispText[DISP_TEXT_SIZE] = { 0 };
+ INT max_cx = 0;
+ HDITEMW hdi;
- TRACE("(iCol=%d, cx=%d\n", iCol, cx);
+ TRACE("(nColumn=%d, cx=%d\n", nColumn, cx);
/* set column width only if in report or list mode */
if (uView != LVS_REPORT && uView != LVS_LIST) return FALSE;
@@ -6148,117 +6137,81 @@
return TRUE;
}
- /* FIXME: update COLUMN_INFO */
+ if (nColumn < 0 || nColumn >= infoPtr->hdpaColumns->nItemCount) return FALSE;
+
+ if (cx == LVSCW_AUTOSIZE || (cx == LVSCW_AUTOSIZE_USEHEADER && nColumn < infoPtr->hdpaColumns->nItemCount -1))
+ {
+ INT nLabelWidth;
+ LVITEMW lvItem;
+
+ lvItem.mask = LVIF_TEXT;
+ lvItem.iItem = 0;
+ lvItem.iSubItem = nColumn;
+ lvItem.pszText = szDispText;
+ lvItem.cchTextMax = DISP_TEXT_SIZE;
+ for (; lvItem.iItem < infoPtr->nItemCount; lvItem.iItem++)
+ {
+ if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) continue;
+ nLabelWidth = LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
+ if (max_cx < nLabelWidth) max_cx = nLabelWidth;
+ }
+ if (infoPtr->himlSmall && (nColumn == 0 || (LISTVIEW_GetColumnInfo(infoPtr, nColumn)->fmt & LVCFMT_IMAGE)))
+ max_cx += infoPtr->iconSize.cx + IMAGE_PADDING;
+ max_cx += REPORT_MARGINX + TRAILING_PADDING;
+ }
/* autosize based on listview items width */
if(cx == LVSCW_AUTOSIZE)
- {
- /* set the width of the column to the width of the widest item */
- if (iCol == 0 || uView == LVS_LIST)
- {
- cx = 0;
- for(item_index = 0; item_index < infoPtr->nItemCount; item_index++)
- {
- nLabelWidth = LISTVIEW_GetLabelWidth(infoPtr, item_index);
- cx = (nLabelWidth>cx)?nLabelWidth:cx;
- }
- if (infoPtr->himlSmall)
- cx += infoPtr->iconSize.cx + IMAGE_PADDING;
- }
- else
- {
- lvItem.iSubItem = iCol;
- lvItem.mask = LVIF_TEXT;
- lvItem.pszText = szDispText;
- lvItem.cchTextMax = DISP_TEXT_SIZE;
- cx = 0;
- for(item_index = 0; item_index < infoPtr->nItemCount; item_index++)
- {
- lvItem.iItem = item_index;
- if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) continue;
- nLabelWidth = LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
- cx = (nLabelWidth>cx)?nLabelWidth:cx;
- }
- }
- cx += TRAILING_PADDING;
- } /* autosize based on listview header width */
+ cx = max_cx;
else if(cx == LVSCW_AUTOSIZE_USEHEADER)
{
- header_item_count = infoPtr->hdpaColumns->nItemCount;
+ /* if iCol is the last column make it fill the remainder of the controls width */
+ if(nColumn == infoPtr->hdpaColumns->nItemCount - 1)
+ {
+ RECT rcHeader;
+ POINT Origin;
- /* if iCol is the last column make it fill the remainder of the controls width */
- if(iCol == (header_item_count - 1)) {
- cx = 0;
+ LISTVIEW_GetOrigin(infoPtr, &Origin);
+ LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcHeader);
- for(item_index = 0; item_index < (header_item_count - 1); item_index++)
+ cx = infoPtr->rcList.right - Origin.x - rcHeader.left;
+ }
+ else
{
- LISTVIEW_GetHeaderRect(infoPtr, item_index, &rcHeader);
- cx += rcHeader.right - rcHeader.left;
- }
-
- /* retrieve the layout of the header */
- GetWindowRect(infoPtr->hwndHeader, &rcHeader);
-
- cx = (rcHeader.right - rcHeader.left) - cx;
- }
- else
- {
- /* Despite what the MS docs say, if this is not the last
- column, then MS resizes the column to the width of the
- largest text string in the column, including headers
- and items. This is different from LVSCW_AUTOSIZE in that
- LVSCW_AUTOSIZE ignores the header string length.
- */
-
- /* retrieve header font */
- header_font = SendMessageW(infoPtr->hwndHeader, WM_GETFONT, 0L, 0L);
-
- /* retrieve header text */
- hdi.mask = HDI_TEXT;
- hdi.cchTextMax = sizeof(text_buffer)/sizeof(text_buffer[0]);
- hdi.pszText = text_buffer;
-
- Header_GetItemW(infoPtr->hwndHeader, iCol, (LPARAM)(&hdi));
-
- /* determine the width of the text in the header */
- hdc = GetDC(infoPtr->hwndSelf);
- old_font = SelectObject(hdc, header_font); /* select the font into hdc */
-
- GetTextExtentPoint32W(hdc, text_buffer, lstrlenW(text_buffer), &size);
-
- SelectObject(hdc, old_font); /* restore the old font */
- ReleaseDC(infoPtr->hwndSelf, hdc);
-
- lvItem.iSubItem = iCol;
- lvItem.mask = LVIF_TEXT;
- lvItem.pszText = szDispText;
- lvItem.cchTextMax = DISP_TEXT_SIZE;
- cx = size.cx;
- for(item_index = 0; item_index < infoPtr->nItemCount; item_index++)
- {
- lvItem.iItem = item_index;
- if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) continue;
- nLabelWidth = LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
- nLabelWidth += TRAILING_PADDING;
- /* While it is possible for subitems to have icons, even MS messes
- up the positioning, so I suspect no applications actually use
- them. */
- if (item_index == 0 && infoPtr->himlSmall)
- nLabelWidth += infoPtr->iconSize.cx + IMAGE_PADDING;
- cx = (nLabelWidth>cx)?nLabelWidth:cx;
- }
- }
- }
-
- /* call header to update the column change */
- hdi.mask = HDI_WIDTH;
-
- hdi.cxy = cx;
- lret = Header_SetItemW(infoPtr->hwndHeader, (WPARAM)iCol, (LPARAM)&hdi);
+ /* Despite what the MS docs say, if this is not the last
+ column, then MS resizes the column to the width of the
+ largest text string in the column, including headers
+ and items. This is different from LVSCW_AUTOSIZE in that
+ LVSCW_AUTOSIZE ignores the header string length. */
+ cx = 0;
+
+ /* retrieve header text */
+ hdi.mask = HDI_TEXT;
+ hdi.cchTextMax = DISP_TEXT_SIZE;
+ hdi.pszText = szDispText;
+ if (Header_GetItemW(infoPtr->hwndHeader, nColumn, (LPARAM)&hdi))
+ {
+ HDC hdc = GetDC(infoPtr->hwndSelf);
+ HFONT old_font = SelectObject(hdc, SendMessageW(infoPtr->hwndHeader, WM_GETFONT, 0, 0));
+ SIZE size;
+
+ if (GetTextExtentPoint32W(hdc, hdi.pszText, lstrlenW(hdi.pszText), &size))
+ cx = size.cx;
+ /* FIXME: Take into account the header image, if one is present */
+ SelectObject(hdc, old_font);
+ ReleaseDC(infoPtr->hwndSelf, hdc);
+ }
+ cx = max (cx, max_cx);
+ }
+ }
- LISTVIEW_InvalidateList(infoPtr); /* FIXME: optimize */
+ if (cx < 0) return FALSE;
- return lret;
+ /* call header to update the column change */
+ hdi.mask = HDI_WIDTH;
+ hdi.cxy = cx;
+ TRACE("hdi.cxy=%d\n", hdi.cxy);
+ return Header_SetItemW(infoPtr->hwndHeader, nColumn, (LPARAM)&hdi);
}
/***
@@ -6365,8 +6318,7 @@
{
INT cy = HIWORD(spacing), cx = LOWORD(spacing);
DWORD oldspacing = MAKELONG(infoPtr->iconSpacing.cx, infoPtr->iconSpacing.cy);
- LONG lStyle = infoPtr->dwStyle;
- UINT uView = lStyle & LVS_TYPEMASK;
+ UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
TRACE("requested=(%d,%d)\n", cx, cy);
More information about the wine-patches
mailing list