Duplicate: Listview update - LVM_GETITEMRECT
Guy L. Albertelli
galberte at neo.lrun.com
Tue Sep 10 21:26:37 CDT 2002
Alexandre: Is this format any better. I am worried about line end characters and line wrapping.
This is the base for the next patch (soon) that will fix the drawing of the
large icons (bugs 676 and #239). This one doesn't really fix any of the
drawing issues but does get the LVM_GETITEMRECT correct for the LVIR_BOUNDS,
LVIR_ICON, and LVIR_LABEL.
This is built on top of CVS of yesterday (9/9/02) but will probably conflict
with Dimi's latest patch.
Guy
License: X11
Changelog:
Guy Albertelli <<galberte at neo.lrun.com>>
dlls/comctl32/listview.c
- Improve LVM_GETITEMRECT values for LVS_ICON style. Now mostly correct
(or atleast matches native).
- Handle focused and selected large icon text better.
- Handle internal erase.
- Fix initial WM_NOTIFYFORMAT.- additional debugging code
- Base for next patch.
Index: dlls/comctl32/listview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/listview.c,v
retrieving revision 1.139
diff -u -r1.139 listview.c
--- dlls/comctl32/listview.c 9 Sep 2002 19:22:19 -0000 1.139
+++ dlls/comctl32/listview.c 11 Sep 2002 01:57:43 -0000
@@ -1,3 +1,5 @@
+#define LISTVIEW_DEBUG 0
+
/*
* Listview control
*
@@ -192,13 +194,13 @@
* ICON_TOP_PADDING_HITABLE - spacing between above and icon.
* ICON_TOP_PADDING - sum of the two above.
* ICON_BOTTOM_PADDING - between bottom of icon and top of text
- * LABEL_VERT_OFFSET - between bottom of text and end of box
+ * LABEL_VERT_PADDING - between bottom of text and end of box
*/
#define ICON_TOP_PADDING_NOTHITABLE 2
#define ICON_TOP_PADDING_HITABLE 2
-#define ICON_TOP_PADDING ICON_TOP_PADDING_NOTHITABLE + ICON_TOP_PADDING_HITABLE
-#define ICON_BOTTOM_PADDING 4
-#define LABEL_VERT_OFFSET 10
+#define ICON_TOP_PADDING (ICON_TOP_PADDING_NOTHITABLE + ICON_TOP_PADDING_HITABLE)
+#define ICON_BOTTOM_PADDING 4
+#define LABEL_VERT_PADDING 7
/* default label width for items in list and small icon display modes */
#define DEFAULT_LABEL_WIDTH 40
@@ -217,6 +219,10 @@
/* Border for the icon caption */
#define CAPTION_BORDER 2
+
+/* Standard DrawText flags for LISTVIEW_UpdateLargeItemLabelRect and LISTVIEW_DrawLargeItem */
+#define LISTVIEW_DTFLAGS DT_TOP | DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_EDITCONTROL
+
/*
* macros
*/
@@ -278,6 +284,7 @@
static VOID LISTVIEW_RemoveSelectionRange(LISTVIEW_INFO *, INT, INT);
static void LISTVIEW_FillBackground(LISTVIEW_INFO *, HDC, LPRECT);
static void LISTVIEW_UpdateLargeItemLabelRect (LISTVIEW_INFO *, int, RECT*);
+static void LISTVIEW_SuperFillBackground(LISTVIEW_INFO *, HDC, LPRECT, COLORREF);
static LRESULT LISTVIEW_GetColumnT(LISTVIEW_INFO *, INT, LPLVCOLUMNW, BOOL);
static LRESULT LISTVIEW_VScroll(LISTVIEW_INFO *, INT, SHORT, HWND);
static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *, INT, SHORT, HWND);
@@ -395,6 +402,20 @@
return notify(infoPtr, code, (LPNMHDR)plvnm);
}
+#if LISTVIEW_DEBUG
+static void LISTVIEW_InvRect(int line, HWND hwnd, const RECT* lprc, BOOL bol)
+{
+ if (lprc)
+ TRACE("doing InvalidateRect at line %d, rect=(%d,%d)-(%d,%d), bool=%d\n",
+ line, lprc->left, lprc->top, lprc->right, lprc->bottom, bol);
+ else
+ TRACE("doing InvalidateRect at line %d, rect=<null>, bool=%d\n",
+ line, bol);
+ InvalidateRect(hwnd, lprc, bol);
+}
+#define InvalidateRect(a,b,c) LISTVIEW_InvRect(__LINE__, a, b, c)
+#endif
+
static int tabNotification[] = {
LVN_BEGINLABELEDITW, LVN_BEGINLABELEDITA,
LVN_ENDLABELEDITW, LVN_ENDLABELEDITA,
@@ -548,9 +569,13 @@
TRACE("listview %08x at line %d, himlNor=%p, himlSml=%p, himlState=%p, Focused=%d, Hot=%d, exStyle=0x%08lx\n",
iP->hwndSelf, line, iP->himlNormal, iP->himlSmall, iP->himlState,
iP->nFocusedItem, iP->nHotItem, iP->dwExStyle);
- TRACE("listview %08x at line %d, ntmH=%d, icSz.cx=%ld, icSz.cy=%ld, icSp.cx=%ld, icSp.cy=%ld\n",
+ TRACE("listview %08x at line %d, ntmH=%d, icSz.cx=%ld, icSz.cy=%ld, icSp.cx=%ld, icSp.cy=%ld, notifyFmt=%d\n",
iP->hwndSelf, line, iP->ntmHeight, iP->iconSize.cx, iP->iconSize.cy,
- iP->iconSpacing.cx, iP->iconSpacing.cy);
+ iP->iconSpacing.cx, iP->iconSpacing.cy, iP->notifyFormat);
+ TRACE("listview %08x at line %d, rcList=(%d,%d)-(%d,%d), rcView=(%d,%d)-(%d,%d)\n",
+ iP->hwndSelf, line,
+ iP->rcList.left, iP->rcList.top, iP->rcList.right, iP->rcList.bottom,
+ iP->rcView.left, iP->rcView.top, iP->rcView.right, iP->rcView.bottom);
}
static BOOL
@@ -3300,10 +3325,9 @@
{
WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
LVITEMW lvItem;
- UINT uFormat = DT_TOP | DT_CENTER | DT_WORDBREAK | DT_NOPREFIX |
- DT_EDITCONTROL ;
- /* Maintain this format in line with the one in LISTVIEW_UpdateLargeItemLabelRect*/
- RECT rcTemp;
+ UINT uFormat = LISTVIEW_DTFLAGS;
+ COLORREF clrFill;
+ RECT rcFill;
TRACE("(hdc=%x, nItem=%d, left=%d, top=%d, right=%d, bottom=%d)\n",
hdc, nItem, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);
@@ -3320,18 +3344,19 @@
LISTVIEW_GetItemW(infoPtr, &lvItem, FALSE);
TRACE(" lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
- /* redraw the background of the item */
- rcTemp = rcItem;
- if(infoPtr->nColumnCount == (nItem + 1))
- rcTemp.right = infoPtr->rcList.right;
- else
- rcTemp.right+=WIDTH_PADDING;
- /* The comment doesn't say WIDTH_PADDING applies to large icons */
+ rcFill = rcItem;
TRACE("background rect (%d,%d)-(%d,%d)\n",
- rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom);
+ rcFill.left, rcFill.top, rcFill.right, rcFill.bottom);
- LISTVIEW_FillBackground(infoPtr, hdc, &rcTemp);
+ /* Paint background of icon and basic text area */
+ clrFill = infoPtr->clrBk;
+#if LISTVIEW_DEBUG
+ clrFill = 0x00f01000;
+ TRACE("background rect (%d,%d)-(%d,%d) special fill\n",
+ rcFill.left, rcFill.top, rcFill.right, rcFill.bottom);
+#endif
+ LISTVIEW_SuperFillBackground(infoPtr, hdc, &rcFill, clrFill);
/* Figure out text colours etc. depending on state
@@ -3400,6 +3425,8 @@
ImageList_Draw (infoPtr->himlNormal, lvItem.iImage, hdc, rcItem.left,
rcItem.top,
(lvItem.state & LVIS_SELECTED) ? ILD_SELECTED : ILD_NORMAL);
+ TRACE("icon %d at (%d,%d)\n",
+ lvItem.iImage, rcItem.left, rcItem.top);
}
}
@@ -3420,6 +3447,17 @@
TRACE("bound box for text+icon (%d,%d)-(%d,%d), iS.cx=%ld, nItemWidth=%d\n",
rcItem.left, rcItem.top, rcItem.right, rcItem.bottom,
infoPtr->iconSize.cx, infoPtr->nItemWidth);
+
+#if LISTVIEW_DEBUG
+ {
+ POINT point[2];
+ memcpy(&point, &rcItem, sizeof(RECT));
+ MapWindowPoints(hwnd, HWND_DESKTOP, point, 2);
+ TRACE("bound box in win coord (%ld,%ld)-(%ld,%ld)\n",
+ point[0].x, point[0].y, point[1].x, point[1].y);
+ }
+#endif
+
TRACE("rcList (%d,%d)-(%d,%d), rcView (%d,%d)-(%d,%d)\n",
infoPtr->rcList.left, infoPtr->rcList.top,
infoPtr->rcList.right, infoPtr->rcList.bottom,
@@ -3468,6 +3506,9 @@
* background?
*/
DrawTextW (hdc, lvItem.pszText, -1, &rcItem, uFormat);
+ TRACE("text at (%d,%d)-(%d,%d) is %s\n",
+ rcItem.left, rcItem.top, rcItem.right, rcItem.bottom,
+ debugstr_w(lvItem.pszText));
CopyRect(SuggestedFocus, &rcItem);
}
@@ -3825,6 +3866,7 @@
RECT rcItem, SuggestedFocus, rcTemp;
INT i;
DWORD cditemmode = CDRF_DODEFAULT;
+ COLORREF clrFill;
TRACE("\n");
infoPtr->nColumnCount = 1; /* set this to an arbitrary value to prevent */
@@ -3832,7 +3874,14 @@
/* paint the background of the control that doesn't contain any items */
SubtractRect(&rcTemp, &infoPtr->rcList, &infoPtr->rcView);
- LISTVIEW_FillBackground(infoPtr, hdc, &rcTemp);
+
+ TRACE("filling viewable area (%d,%d)-(%d,%d)\n",
+ rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom);
+ clrFill = infoPtr->clrBk;
+#if LISTVIEW_DEBUG
+ clrFill = 0x000004010;
+#endif
+ LISTVIEW_SuperFillBackground(infoPtr, hdc, &rcTemp, clrFill);
/* nothing to draw, return here */
if(GETITEMCOUNT(infoPtr) == 0)
@@ -5510,6 +5559,36 @@
}
/***
+ * Adjust a text rectangle to an integral number of text lines.
+ */
+static void LISTVIEW_GetIntegralLines(
+ const LISTVIEW_INFO *infoPtr,
+ RECT *rcText)
+{
+ INT i, j, k, l;
+
+ /*
+ * We need to have the bottom to be an intergal number of
+ * text lines (ntmHeight) below text top that is less than
+ * or equal to the nItemHeight.
+ */
+ i = infoPtr->nItemHeight - infoPtr->iconSize.cy -
+ ICON_TOP_PADDING - ICON_BOTTOM_PADDING;
+ j = i / infoPtr->ntmHeight;
+ k = j * infoPtr->ntmHeight;
+ l = rcText->top + k;
+ rcText->bottom = min(rcText->bottom, l);
+ rcText->bottom += 1;
+
+ TRACE("integral lines, nitemH=%d, ntmH=%d, icon.cy=%ld, i=%d, j=%d, k=%d, rect=(%d,%d)-(%d,%d)\n",
+ infoPtr->nItemHeight, infoPtr->ntmHeight, infoPtr->iconSize.cy,
+ i, j, k,
+ rcText->left, rcText->top, rcText->right, rcText->bottom);
+}
+
+
+/***
+ * DESCRIPTION: [INTERNAL]
* Update the bounding rectangle around the text under a large icon.
* This depends on whether it has the focus or not.
* On entry the rectangle's top, left and right should be set.
@@ -5527,8 +5606,23 @@
{
HDC hdc = GetDC (infoPtr->hwndSelf);
HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
+ UINT uFormat = LISTVIEW_DTFLAGS | DT_CALCRECT;
+ RECT rcText = *rect;
+ RECT rcBack = *rect;
+ BOOL focused, selected;
+ int dx, dy, old_wid, new_wid;
+
+ TRACE("%s, focus item=%d, cur item=%d\n",
+ (infoPtr->bFocus) ? "Window has focus" : "Window not focused",
+ infoPtr->nFocusedItem, nItem);
+
+
+ focused = (infoPtr->bFocus && infoPtr->nFocusedItem == nItem);
+ selected = LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED);
- if (infoPtr->bFocus && infoPtr->nFocusedItem == nItem)
+ uFormat |= (focused) ? DT_NOCLIP : DT_WORD_ELLIPSIS | DT_END_ELLIPSIS;
+
+ if (focused || selected)
{
/* We (aim to) display the full text. In Windows 95 it appears to
* calculate the size assuming the specified font and then it draws
@@ -5549,10 +5643,31 @@
* to copy it.
*/
LISTVIEW_GetItemW (infoPtr, &lvItem, TRUE);
- DrawTextW (hdc, lvItem.pszText, -1, rect, DT_CALCRECT |
- DT_NOCLIP | DT_EDITCONTROL | DT_TOP | DT_CENTER |
- DT_WORDBREAK | DT_NOPREFIX);
- /* Maintain this DT_* list in line with LISTVIEW_DrawLargeItem */
+
+ InflateRect(&rcText, -2, 0);
+ DrawTextW (hdc, lvItem.pszText, -1, &rcText, uFormat);
+ /* Microsoft, in their great wisdom, have decided that the rectangle
+ * returned by DrawText on DT_CALCRECT will only guarantee the dimension,
+ * not the location. So we have to do the centring ourselves (and take
+ * responsibility for agreeing off-by-one consistency with them).
+ */
+
+ old_wid = rcText.right - rcText.left;
+ new_wid = rcBack.right - rcBack.left;
+ dx = rcBack.left - rcText.left + (new_wid-old_wid)/2;
+ dy = rcBack.top - rcText.top;
+ OffsetRect (&rcText, dx, dy);
+
+ if (!focused)
+ {
+ LISTVIEW_GetIntegralLines(infoPtr, &rcText);
+ }
+ else
+ {
+ rcText.bottom += LABEL_VERT_PADDING - 2;
+ }
+ *rect = rcBack;
+ rect->bottom = rcText.bottom;
}
else
{
@@ -5565,9 +5680,15 @@
* Question; should the width be shrunk to the space required to
* display the two lines?
*/
- rect->bottom = rect->top + 2 * infoPtr->ntmHeight;
+ LISTVIEW_GetIntegralLines(infoPtr, &rcText);
+ rect->bottom = rcText.bottom;
}
+ TRACE("%s and %s, bounding rect=(%d,%d)-(%d,%d)\n",
+ (focused) ? "focused(full text)" : "not focused",
+ (selected) ? "selected" : "not selected",
+ rect->left, rect->top, rect->right, rect->bottom);
+
SelectObject (hdc, hOldFont);
ReleaseDC (infoPtr->hwndSelf, hdc);
}
@@ -5585,8 +5706,41 @@
*
* LVIR_BOUNDS Returns the bounding rectangle of the entire item,
* including the icon and label.
+ * *
+ * * For LVS_ICON
+ * * Experiment shows that native control returns:
+ * * width = min (48, length of text line)
+ * * .left = position.x - (width - iconsize.cx)/2
+ * * .right = .left + width
+ * * height = #lines of text * ntmHeight + icon height + 8
+ * * .top = position.y - 2
+ * * .bottom = .top + height
+ * * separation between items .y = itemSpacing.cy - height
+ * * .x = itemSpacing.cx - width
* LVIR_ICON Returns the bounding rectangle of the icon or small icon.
+ * *
+ * * For LVS_ICON
+ * * Experiment shows that native control returns:
+ * * width = iconSize.cx + 16
+ * * .left = position.x - (width - iconsize.cx)/2
+ * * .right = .left + width
+ * * height = iconSize.cy + 4
+ * * .top = position.y - 2
+ * * .bottom = .top + height
+ * * separation between items .y = itemSpacing.cy - height
+ * * .x = itemSpacing.cx - width
* LVIR_LABEL Returns the bounding rectangle of the item text.
+ * *
+ * * For LVS_ICON
+ * * Experiment shows that native control returns:
+ * * width = text length
+ * * .left = position.x - width/2
+ * * .right = .left + width
+ * * height = ntmH * linecount + 2
+ * * .top = position.y + iconSize.cy + 6
+ * * .bottom = .top + height
+ * * separation between items .y = itemSpacing.cy - height
+ * * .x = itemSpacing.cx - width
* LVIR_SELECTBOUNDS Returns the union of the LVIR_ICON and LVIR_LABEL
* rectangles, but excludes columns in report view.
*
@@ -5612,7 +5766,8 @@
LVITEMW lvItem;
RECT rcInternal;
- TRACE("(nItem=%d, lprc=%p)\n", nItem, lprc);
+ TRACE("(hwnd=%x, nItem=%d, lprc=%p, uview=%d)\n",
+ infoPtr->hwndSelf, nItem, lprc, uView);
if (uView & LVS_REPORT)
{
@@ -5644,11 +5799,11 @@
if (LISTVIEW_GetOrigin(infoPtr, &ptOrigin) != FALSE)
{
bResult = TRUE;
- lprc->left = ptItem.x + ptOrigin.x;
- lprc->top = ptItem.y + ptOrigin.y;
- lprc->right = lprc->left + infoPtr->iconSize.cx;
- lprc->bottom = (lprc->top + infoPtr->iconSize.cy +
- ICON_BOTTOM_PADDING + ICON_TOP_PADDING);
+ lprc->left = ptItem.x + ptOrigin.x - 8;
+ lprc->top = ptItem.y + ptOrigin.y - ICON_TOP_PADDING;
+ lprc->right = lprc->left + infoPtr->iconSize.cx + 16;
+ lprc->bottom = lprc->top + infoPtr->iconSize.cy +
+ ICON_TOP_PADDING;
}
}
}
@@ -5698,22 +5853,29 @@
if (LISTVIEW_GetOrigin(infoPtr, &ptOrigin) != FALSE)
{
bResult = TRUE;
+
+ /* Correct ptItem to icon upper-left */
+ ptItem.x -= (infoPtr->nItemWidth - infoPtr->iconSize.cx)/2;
+ ptItem.y -= ICON_TOP_PADDING;
+
lprc->left = ptItem.x + ptOrigin.x;
- lprc->top = (ptItem.y + ptOrigin.y + infoPtr->iconSize.cy +
- ICON_BOTTOM_PADDING);
+ lprc->top = ptItem.y + ptOrigin.y + infoPtr->iconSize.cy +
+ 6;
nLabelWidth = LISTVIEW_GetLabelWidth(infoPtr, nItem);
if (infoPtr->iconSpacing.cx - nLabelWidth > 1)
{
lprc->left += (infoPtr->iconSpacing.cx - nLabelWidth) / 2;
lprc->right = lprc->left + nLabelWidth;
- }
+ lprc->bottom = lprc->top + infoPtr->ntmHeight + 1;
+ InflateRect(lprc, 2, 0);
+ }
else
{
- lprc->left += 1;
lprc->right = lprc->left + infoPtr->iconSpacing.cx - 1;
+ lprc->bottom = lprc->top + infoPtr->nItemHeight;
LISTVIEW_UpdateLargeItemLabelRect (infoPtr, nItem, lprc);
}
- lprc->bottom = lprc->top + infoPtr->ntmHeight + HEIGHT_PADDING;
+ lprc->bottom += HEIGHT_PADDING;
}
}
}
@@ -5782,48 +5944,42 @@
{
if (LISTVIEW_GetOrigin(infoPtr, &ptOrigin) != FALSE)
{
- RECT label_rect;
- INT text_left, text_right, icon_left, text_pos_x;
- /* for style LVS_ICON bounds
- * left = min(icon.left, text.left)
- * right = max(icon.right, text.right)
- * top = boundbox.top + NOTHITABLE
- * bottom = text.bottom + 1
- */
- bResult = TRUE;
- icon_left = text_left = ptItem.x;
+ RECT label_rect, icon_rect;
+
+ if (!LISTVIEW_GetItemPosition(infoPtr, nItem, &ptItem)) break;
+ /* make icon rectangle */
+ icon_rect.left = ptItem.x + ptOrigin.x - 8;
+ icon_rect.top = ptItem.y + ptOrigin.y - ICON_TOP_PADDING;
+ icon_rect.right = icon_rect.left + infoPtr->iconSize.cx + 16;
+ icon_rect.bottom = icon_rect.top + infoPtr->iconSize.cy +
+ ICON_TOP_PADDING;
+
+ /* make label rectangle */
/* Correct ptItem to icon upper-left */
- icon_left += (infoPtr->nItemWidth - infoPtr->iconSize.cx)/2;
- ptItem.y += ICON_TOP_PADDING;
+ ptItem.x -= (infoPtr->nItemWidth - infoPtr->iconSize.cx)/2;
+ ptItem.y -= ICON_TOP_PADDING;
- /* Compute the label left and right */
- nLabelWidth = LISTVIEW_GetLabelWidth(infoPtr, nItem);
- text_pos_x = infoPtr->iconSpacing.cx - 2*CAPTION_BORDER - nLabelWidth;
- if (text_pos_x > 1)
- {
- text_left += text_pos_x / 2;
- text_right = text_left + nLabelWidth + 2*CAPTION_BORDER;
- }
- else
- {
- text_left += 1;
- text_right = text_left + infoPtr->iconSpacing.cx - 1;
- }
-
- /* Compute rectangle w/o the text height */
- lprc->left = min(icon_left, text_left) + ptOrigin.x;
- lprc->right = max(icon_left + infoPtr->iconSize.cx,
- text_right) + ptOrigin.x;
- lprc->top = ptItem.y + ptOrigin.y - ICON_TOP_PADDING_HITABLE;
- lprc->bottom = lprc->top + ICON_TOP_PADDING_HITABLE
- + infoPtr->iconSize.cy + 1
- + ICON_BOTTOM_PADDING;
-
- CopyRect (&label_rect, lprc);
- label_rect.top = lprc->bottom;
- LISTVIEW_UpdateLargeItemLabelRect (infoPtr, nItem, &label_rect);
- UnionRect (lprc, lprc, &label_rect);
+ label_rect.left = ptItem.x + ptOrigin.x;
+ label_rect.top = ptItem.y + ptOrigin.y + infoPtr->iconSize.cy +
+ 6;
+ nLabelWidth = LISTVIEW_GetLabelWidth(infoPtr, nItem);
+ if (infoPtr->iconSpacing.cx - nLabelWidth > 1)
+ {
+ label_rect.left += (infoPtr->iconSpacing.cx - nLabelWidth) / 2;
+ label_rect.right = label_rect.left + nLabelWidth;
+ label_rect.bottom = label_rect.top + infoPtr->ntmHeight + 1;
+ InflateRect(&label_rect, 2, 0);
+ }
+ else
+ {
+ label_rect.right = label_rect.left + infoPtr->iconSpacing.cx - 1;
+ label_rect.bottom = label_rect.top + infoPtr->nItemHeight;
+ LISTVIEW_UpdateLargeItemLabelRect (infoPtr, nItem, &label_rect);
+ }
+ label_rect.bottom += HEIGHT_PADDING;
+ bResult = TRUE;
+ UnionRect (lprc, &icon_rect, &label_rect);
}
}
}
@@ -5968,9 +6124,6 @@
}
break;
}
- TRACE("result %s (%d,%d)-(%d,%d)\n",
- (bResult) ? "TRUE" : "FALSE",
- lprc->left, lprc->top, lprc->right, lprc->bottom);
}
TRACE("result %s (%d,%d)-(%d,%d)\n", bResult ? "TRUE" : "FALSE",
@@ -7525,8 +7678,8 @@
{ /* if 0 then compute height */
if (uView == LVS_ICON)
infoPtr->iconSpacing.cy = infoPtr->iconSize.cy + 2 * infoPtr->ntmHeight
- + ICON_BOTTOM_PADDING + ICON_TOP_PADDING + LABEL_VERT_OFFSET;
- /* FIXME. I don't think so; I think it is based on twice the ntmHeight */
+ + ICON_BOTTOM_PADDING + ICON_TOP_PADDING + LABEL_VERT_PADDING;
+
else /* FIXME: unknown computation for non LVS_ICON - this is a guess */
infoPtr->iconSpacing.cy = LISTVIEW_GetItemHeight(infoPtr);
}
@@ -8062,6 +8215,9 @@
/* initialize info pointer */
ZeroMemory(infoPtr, sizeof(LISTVIEW_INFO));
+ /* set my handle for all the other routines */
+ infoPtr->hwndSelf = hwnd;
+
/* determine the type of structures to use */
infoPtr->notifyFormat = SendMessageW(GetParent(infoPtr->hwndSelf), WM_NOTIFYFORMAT,
(WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);
@@ -8072,7 +8228,6 @@
infoPtr->clrTextBk = CLR_DEFAULT;
/* set default values */
- infoPtr->hwndSelf = hwnd;
infoPtr->uCallbackMask = 0;
infoPtr->nFocusedItem = -1;
infoPtr->nSelectionMark = -1;
@@ -8174,6 +8329,7 @@
if (infoPtr->clrBk == CLR_NONE)
{
bResult = SendMessageW(GetParent(infoPtr->hwndSelf), WM_ERASEBKGND, wParam, lParam);
+ TRACE("erase CLR_NONE result=%d\n", bResult);
}
else
{
@@ -8182,6 +8338,8 @@
GetClientRect(infoPtr->hwndSelf, &rc);
FillRect((HDC)wParam, &rc, hBrush);
DeleteObject(hBrush);
+ TRACE("erase rect=(%d,%d)-(%d,%d), clrBk=0x%08lx\n",
+ rc.left, rc.top, rc.right, rc.bottom, infoPtr->clrBk);
bResult = TRUE;
}
@@ -8191,16 +8349,40 @@
static void LISTVIEW_FillBackground(LISTVIEW_INFO *infoPtr, HDC hdc, LPRECT rc)
{
- TRACE("(hdc=%x, rc=%p)\n", hdc, rc);
+ TRACE("(hwnd=%x, hdc=%x, clrBk=0x%08lx, rc=(%d,%d)-(%d,%d))\n",
+ infoPtr->hwndSelf, hdc, infoPtr->clrBk,
+ rc->left, rc->top, rc->right, rc->bottom);
if (infoPtr->clrBk != CLR_NONE)
{
- HBRUSH hBrush = CreateSolidBrush(infoPtr->clrBk);
+#if LISTVIEW_DEBUG
+ COLORREF clrbrsh = 0x00c08040;
+#else
+ COLORREF clrbrsh = infoPtr->clrBk;
+#endif
+ HBRUSH hBrush = CreateSolidBrush(clrbrsh);
FillRect(hdc, rc, hBrush);
DeleteObject(hBrush);
}
}
+static void LISTVIEW_SuperFillBackground(LISTVIEW_INFO *infoPtr, HDC hdc,
+ LPRECT rc, COLORREF clrbrsh)
+{
+ TRACE("(hwnd=%x, hdc=%x, clrBk=0x%08lx, rc=(%d,%d)-(%d,%d))\n",
+ infoPtr->hwndSelf, hdc, infoPtr->clrBk,
+ rc->left, rc->top, rc->right, rc->bottom);
+
+#if !LISTVIEW_DEBUG
+ if (infoPtr->clrBk != CLR_NONE)
+#endif
+ {
+ HBRUSH hBrush = CreateSolidBrush(clrbrsh);
+ FillRect(hdc, rc, hBrush);
+ DeleteObject(hBrush);
+ }
+}
+
/***
* DESCRIPTION:
* Retrieves the listview control font.
@@ -8726,6 +8908,12 @@
TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, pts.x, pts.y);
+ /* FIXME???? native does
+ * SetCapture(hwnd);
+ * ReleaseCapture();
+ * prior to the notify
+ */
+
/* send NM_RELEASEDCAPTURE notification */
hdr_notify(infoPtr, NM_RELEASEDCAPTURE);
@@ -8768,9 +8956,44 @@
BOOL was_selected =
(LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED) & LVIS_SELECTED);
+ /* FIXME?? native does:
+ * RegQueryValueA (0, 0, "AppEvents\\Schemes\\Apps\\.Default\\CCSelect\\.current"
+ * gets "c:\\windows\media\\hoversel.wav"
+ * LoadLibrary("winmm.dll")
+ * GetProcAddress("waveOutGetNumDevs")
+ * GetProcAddress("PlaySoundW")
+ * waveOutGetNumDevs()
+ * PlaySoundW(...)
+ * GetDoubleClickTime()
+ * SetTimer(hwnd, 2b, time, 0)
+ */
+
/* set selection (clears other pre-existing selections) */
LISTVIEW_SetSelection(infoPtr, nItem);
+ /* FIXME?? native does:
+ * notify LVN_ITEMCHANGING
+ * SendMessage(tooltips, 0x41c, 0, 0)
+ * UnionRect(&target, iconrect?, textrect?)
+ * RedrawWindow(hwnd, &target, 0, 1)
+ * notify LVN_ITEMCHANGED
+ * GetFocus()
+ * NotifyWinEvent(0008005, hwnd, -4, 7)
+ * NotifyWinEvent(0008006, hwnd, -4, 7)
+ * GetSystemMetrics(0x44)
+ * GetSystemMetrics(0x45)
+ * SetRect(&a, 0x1f5, 0x20, 0x1fd, 0x28)
+ * MapWindowPoints(hwnd, 0, &a, 2)
+ * SetCapture(hwnd)
+ * PeekMessage(???, 0, 0, 0, 1)
+ * CallMsgFilterA(???, 0x00004200)
+ * ReleaseCapture()
+ * IsWindow(hwnd)
+ * SetFocus(hwnd)
+ * notify NM_CLICK
+ * return DefWindowProcA()
+ */
+
if (was_selected && infoPtr->nEditLabelItem == -1)
infoPtr->nEditLabelItem = nItem;
}
@@ -9026,6 +9249,11 @@
if (hdc == 0)
{
hdc = BeginPaint(infoPtr->hwndSelf, &ps);
+ TRACE("ps erase=%s, rect=(%d,%d)-(%d,%d)\n",
+ ps.fErase ? "TRUE" : "FALSE",
+ ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
+ if (ps.fErase)
+ LISTVIEW_EraseBackground(infoPtr, (WPARAM)hdc, 0);
LISTVIEW_Refresh(infoPtr, hdc);
EndPaint(infoPtr->hwndSelf, &ps);
}
More information about the wine-patches
mailing list