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