Listview updates (G0)

Dimitrie O. Paun dpaun at rogers.com
Fri Sep 27 08:22:20 CDT 2002


This fixes a number of important bugs, there's still some important
ones left...

ChangeLogs:
  -- Fix craches in debug mode
  -- Fix some focus rectangle problems
  -- Better debugging output
  -- More cleanups.

Index: dlls/comctl32/listview.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/listview.c,v
retrieving revision 1.152
diff -u -r1.152 listview.c
--- dlls/comctl32/listview.c	25 Sep 2002 03:20:01 -0000	1.152
+++ dlls/comctl32/listview.c	26 Sep 2002 15:01:33 -0000
@@ -175,6 +175,10 @@
 /*
  * constants
  */
+/* How many we debug buffer to allocate */
+#define DEBUG_BUFFERS 20
+/* The size of a single debug bbuffer */
+#define DEBUG_BUFFER_SIZE 256
 
 /* Internal interface to LISTVIEW_HScroll and LISTVIEW_VScroll */
 #define SB_INTERNAL      -1
@@ -428,34 +432,87 @@
     return isW ? debugstr_wn(text, n) : debugstr_an((LPCSTR)text, n);
 }
 
-static char* debuglvitem_t(LPLVITEMW lpLVItem, BOOL isW)
+static char* debug_getbuf()
 {
     static int index = 0;
-    static char buffers[20][256];
-    char* buf = buffers[index++ % 20];
+    static char buffers[DEBUG_BUFFERS][DEBUG_BUFFER_SIZE];
+    return buffers[index++ % DEBUG_BUFFERS];
+}
+
+static char* debuglvitem_t(LPLVITEMW lpLVItem, BOOL isW)
+{
+    char* buf = debug_getbuf(), *text = buf;
+    int len, size = DEBUG_BUFFER_SIZE;
+    
     if (lpLVItem == NULL) return "(null)";
-    snprintf(buf, 256, "{mask=%x, iItem=%d, iSubItem=%d, state=%x, stateMask=%x,"
-             " pszText=%s, cchTextMax=%d, iImage=%d, lParam=%lx, iIndent=%d}",
-	     lpLVItem->mask, lpLVItem->iItem, lpLVItem->iSubItem,
-	     lpLVItem->state, lpLVItem->stateMask,
-	     lpLVItem->mask & LVIF_TEXT ? debugtext_tn(lpLVItem->pszText, isW, 80) : 0,
-	     lpLVItem->cchTextMax, lpLVItem->iImage, lpLVItem->lParam,
-	     lpLVItem->iIndent);
-    return buf;
+    len = snprintf(buf, size, "{iItem=%d, iSubItem=%d, ", lpLVItem->iItem, lpLVItem->iSubItem);
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpLVItem->mask & LVIF_STATE)
+	len = snprintf(buf, size, "state=%x, stateMask=%x, ", lpLVItem->state, lpLVItem->stateMask);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpLVItem->mask & LVIF_TEXT)
+	len = snprintf(buf, size, "pszText=%s, cchTextMax=%d, ", debugtext_tn(lpLVItem->pszText, isW, 80), lpLVItem->cchTextMax);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpLVItem->mask & LVIF_IMAGE)
+	len = snprintf(buf, size, "iImage=%d, ", lpLVItem->iImage);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpLVItem->mask & LVIF_PARAM)
+	len = snprintf(buf, size, "lParam=%lx, ", lpLVItem->lParam);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpLVItem->mask & LVIF_INDENT)
+	len = snprintf(buf, size, "iIndent=%d, ", lpLVItem->iIndent);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    goto undo;
+end:
+    buf = text + strlen(text);
+undo:
+    if (buf - text > 2) buf[-2] = '}'; buf[-1] = 0;
+    return text;
 }
 
 static char* debuglvcolumn_t(LPLVCOLUMNW lpColumn, BOOL isW)
 {
-    static int index = 0;
-    static char buffers[20][256];
-    char* buf = buffers[index++ % 20];
+    char* buf = debug_getbuf(), *text = buf;
+    int len, size = DEBUG_BUFFER_SIZE;
+    
     if (lpColumn == NULL) return "(null)";
-    snprintf(buf, 256, "{mask=%x, fmt=%x, cx=%d,"
-             " pszText=%s, cchTextMax=%d, iSubItem=%d}",
-	     lpColumn->mask, lpColumn->fmt, lpColumn->cx,
-	     lpColumn->mask & LVCF_TEXT ? debugtext_tn(lpColumn->pszText, isW, 80): "",
-	     lpColumn->mask & LVCF_TEXT ? lpColumn->cchTextMax: 0, lpColumn->iSubItem);
-    return buf;
+    len = snprintf(buf, size, "{");
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpColumn->mask & LVCF_SUBITEM)
+	len = snprintf(buf, size, "iSubItem=%d, ",  lpColumn->iSubItem);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpColumn->mask & LVCF_FMT)
+	len = snprintf(buf, size, "fmt=%x, ", lpColumn->fmt);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpColumn->mask & LVCF_WIDTH)
+	len = snprintf(buf, size, "cx=%d, ", lpColumn->cx);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpColumn->mask & LVCF_TEXT)
+	len = snprintf(buf, size, "pszText=%s, cchTextMax=%d, ", debugtext_tn(lpColumn->pszText, isW, 80), lpColumn->cchTextMax);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpColumn->mask & LVCF_IMAGE)
+	len = snprintf(buf, size, "iImage=%d, ", lpColumn->iImage);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    if (lpColumn->mask & LVCF_ORDER)
+	len = snprintf(buf, size, "iOrder=%d, ", lpColumn->iOrder);
+    else len = 0;
+    if (len == -1) goto end; buf += len; size -= len;
+    goto undo;
+end:
+    buf = text + strlen(text);
+undo:
+    if (buf - text > 2) buf[-2] = '}'; buf[-1] = 0;
+    return text;
 }
 
 #if 0
@@ -1147,28 +1204,29 @@
 /***
  * DESCRIPTION:            [INTERNAL]
  * Compute sizes and rectangles of an item.  This is to localize all
- * the computations in one place.
+ * the computations in one place. If you are not interested in some
+ * of these values, simply pass in a NULL.
  *
  *                                          supported for style:
  *                                                   IC SI LI RP
  * PARAMETER(S):
- * [I] HWND : window handle
- * [I] INT  : item number
- * [O] LPPOINT : ptr to Origin point or NULL         x  x  x  x
- * [O] LPPOINT : ptr to Position point or NULL       x  x  x  x
+ * [I] infoPtr : valid pointer to the listview structure
+ * [I] nItem  : item number
+ * [O] lpptOrigin : ptr to Origin point              x  x  x  x
+ * [O] lpptPosition : ptr to Position point          x  x  x  x
  *                the Position point is relative to infoPtr->rcList
  *                (has *NOT* been adjusted by the origin)
- * [O] LPRECT  : ptr to Boundary rectangle or NULL   x  x  x  x
+ * [O] lprcBoundary : ptr to Boundary rectangle      x  x  x  x
  *                the Boundary rectangle is relative to infoPtr->rcList
  *                (has *NOT* been adjusted by the origin)
- * [O] LPRECT  : ptr to Icon rectangle or NULL       x  x  x  x
+ * [O] lprcIcon  : ptr to Icon rectangle             x  x  x  x
  *                the Icon rectangle is relative to infoPtr->rcView
  *                (has already been adjusted by the origin)
- * [O] LPRECT  : ptr to Label rectangle or NULL      x  x  -  -
+ * [O] lprcLabel : ptr to Label rectangle            x  x  -  -
  *              - the Label rectangle is relative to infoPtr->rcView
  *                (has already been adjusted by the origin)
  *              - the Label rectangle encloses the label text only
- * [O] LPRECT  : ptr to FullText rectangle or NULL   x  x  -  -
+ * [O] lprcFText : ptr to FullText rectangle         x  x  -  -
  *              - the FullText rectangle is relative to infoPtr->rcView
  *                (has already been adjusted by the origin)
  *              - the FullText rectangle contains the Label rectangle
@@ -1178,58 +1236,53 @@
  *   TRUE if computations OK
  *   FALSE otherwise
  */
-static BOOL LISTVIEW_GetAllMeasure(LISTVIEW_INFO *infoPtr, INT nItem,
-				  LPPOINT lpptOrigin,
-				  LPPOINT lpptPosition,
-				  LPRECT lprcBoundary,
-				  LPRECT lprcIcon,
-				  LPRECT lprcLabel,
-				  LPRECT lprcFText)
+static BOOL LISTVIEW_GetAllMeasures(LISTVIEW_INFO *infoPtr, INT nItem,
+				    LPPOINT lpptOrigin, LPPOINT lpptPosition,
+				    LPRECT lprcBoundary, LPRECT lprcIcon,
+				    LPRECT lprcLabel, LPRECT lprcFText)
 {
-  LONG lStyle = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE);
-  UINT uView = lStyle & LVS_TYPEMASK;
-  BOOL bResult = TRUE;
-  HDPA hdpaSubItems;
-  LISTVIEW_ITEM *lpItem;
-  POINT Origin, Position;
-  RECT Icon, Boundary, Label;
-  INT nHorzPos = 0, nVertPos = 0;
+    LONG lStyle = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE);
+    UINT uView = lStyle & LVS_TYPEMASK;
+    BOOL bResult = TRUE;
+    HDPA hdpaSubItems;
+    LISTVIEW_ITEM *lpItem;
+    POINT Origin, Position;
+    RECT Icon, Boundary, Label;
+    INT nHorzPos = 0, nVertPos = 0;
+    SCROLLINFO scrollInfo;
 
-  /************************************************************/
-  /* compute Origin point                                     */
-  /*  (we can always do this even with bad/invalid nItem)     */
-  /************************************************************/
-  SCROLLINFO scrollInfo;
-  ZeroMemory(&Origin, sizeof(POINT));
-  ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
-  scrollInfo.cbSize = sizeof(SCROLLINFO);    
-  scrollInfo.fMask = SIF_POS;
+    /************************************************************/
+    /* compute Origin point                                     */
+    /*  (we can always do this even with bad/invalid nItem)     */
+    /************************************************************/
+    scrollInfo.cbSize = sizeof(SCROLLINFO);    
+    scrollInfo.fMask = SIF_POS;
     
-  if ((lStyle & WS_HSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo))
-      nHorzPos = scrollInfo.nPos;
-  if ((lStyle & WS_VSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
-      nVertPos = scrollInfo.nPos;
+    if ((lStyle & WS_HSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo))
+	nHorzPos = scrollInfo.nPos;
+    if ((lStyle & WS_VSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
+	nVertPos = scrollInfo.nPos;
 
-  TRACE("nHorzPos=%d, nVertPos=%d\n", nHorzPos, nVertPos);
+    TRACE("nHorzPos=%d, nVertPos=%d\n", nHorzPos, nVertPos);
 
-  Origin.x = infoPtr->rcList.left;
-  Origin.y = infoPtr->rcList.top;
-  if (uView == LVS_LIST)
-      {
-	  nHorzPos *= LISTVIEW_GetCountPerColumn(infoPtr);
-	  nVertPos = 0;
-      }
-  else if (uView == LVS_REPORT)
-      {
-	  nVertPos *= infoPtr->nItemHeight;
-      }
+    Origin.x = infoPtr->rcList.left;
+    Origin.y = infoPtr->rcList.top;
+    if (uView == LVS_LIST)
+    {
+	nHorzPos *= LISTVIEW_GetCountPerColumn(infoPtr);
+	nVertPos = 0;
+    }
+    else if (uView == LVS_REPORT)
+    {
+	nVertPos *= infoPtr->nItemHeight;
+    }
     
-  Origin.x -= nHorzPos;
-  Origin.y -= nVertPos;
+    Origin.x -= nHorzPos;
+    Origin.y -= nVertPos;
 
-  TRACE("hwnd=%x, item=%d, origin=(%ld,%ld)\n",
-	infoPtr->hwndSelf, nItem, Origin.x, Origin.y);
-  if (lpptOrigin) *lpptOrigin = Origin;
+    TRACE("hwnd=%x, item=%d, origin=(%ld,%ld)\n",
+	 infoPtr->hwndSelf, nItem, Origin.x, Origin.y);
+    if (lpptOrigin) *lpptOrigin = Origin;
     
 
   /************************************************************/
@@ -1284,15 +1337,7 @@
                          infoPtr->nItemHeight) + infoPtr->rcList.top;
 
       if (!(lStyle & LVS_NOSCROLL))
-      {
-	  SCROLLINFO scrollInfo;
-	  /* Adjust position by scrollbar offset */
-	  ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
-	  scrollInfo.cbSize = sizeof(SCROLLINFO);
-	  scrollInfo.fMask = SIF_POS;
-	  GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo);
-	  Boundary.left -= scrollInfo.nPos;
-      }
+	  Boundary.left -= nHorzPos;
   }
   Boundary.right = Boundary.left + infoPtr->nItemWidth;
   Boundary.bottom = Boundary.top + infoPtr->nItemHeight;
@@ -2258,7 +2303,6 @@
 
     LISTVIEW_RemoveAllSelections(infoPtr);
 
-    ZeroMemory(&lvItem, sizeof(lvItem));
     lvItem.state = LVIS_FOCUSED | LVIS_SELECTED;
     lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
     LISTVIEW_SetItemState(infoPtr, nItem, &lvItem);
@@ -2598,9 +2642,6 @@
     NMLISTVIEW nmlv;
     UINT uChanged = 0;
 
-    TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);
-
-  
     if (lStyle & LVS_OWNERDATA)
     {
 	INT oldState;
@@ -2764,8 +2805,6 @@
     HDPA hdpaSubItems;
     LISTVIEW_SUBITEM *lpSubItem;
 
-    TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);
-
     if (lStyle & LVS_OWNERDATA) return FALSE;
 
     /* set subitem only if column is present */
@@ -2832,6 +2871,8 @@
     LPWSTR pszText = NULL;
     BOOL bResult;
     
+    TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);
+
     if (!lpLVItem || lpLVItem->iItem < 0 ||
 	lpLVItem->iItem>=GETITEMCOUNT(infoPtr))
 	return FALSE;
@@ -2869,7 +2910,7 @@
 		InvalidateRect(infoPtr->hwndSelf, &rcOldItem, TRUE);
 	}
 
-	LISTVIEW_GetAllMeasure(infoPtr, lpLVItem->iItem, NULL, NULL,
+	LISTVIEW_GetAllMeasures(infoPtr, lpLVItem->iItem, NULL, NULL,
 			      NULL, &rcIcon, NULL, &rcFullText);
 	UnionRect(&rcNewItem, &rcIcon, &rcFullText);
 	if(!IsRectEmpty(&rcNewItem))
@@ -2993,7 +3034,6 @@
   LISTVIEW_GetItemW(infoPtr, &lvItem, TRUE);
   TRACE("   lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
 
-  ZeroMemory(&lvColumn, sizeof(lvColumn));
   lvColumn.mask = LVCF_FMT;
   LISTVIEW_GetColumnT(infoPtr, nSubItem, &lvColumn, TRUE);
   textLeft = rcItem.left;
@@ -3299,7 +3339,7 @@
   LISTVIEW_GetItemW(infoPtr, &lvItem, FALSE);
   TRACE("   lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
 
-  LISTVIEW_GetAllMeasure(infoPtr, nItem, &ptOrg, NULL,
+  LISTVIEW_GetAllMeasures(infoPtr, nItem, &ptOrg, NULL,
 			&rcFill, &rcIcon, &rcLabel, &rcFullText);
   rcFill.left += ptOrg.x;
   rcFill.top += ptOrg.y;
@@ -3564,7 +3604,6 @@
             dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight;
             OffsetRect(&dis.rcItem, ptOrig.x, 0);
 
-            ZeroMemory(&item, sizeof(item));
             item.iItem = nItem;
 	    item.iSubItem = 0;
             item.mask = LVIF_PARAM;
@@ -4668,41 +4707,35 @@
  */
 static INT LISTVIEW_GetNearestItem(LISTVIEW_INFO *infoPtr, POINT pt, UINT vkDirection)
 {
-  LV_INTHIT lvIntHit;
-  INT nItem = -1;
-  RECT rcView;
+    LV_INTHIT lvIntHit;
+    INT nItem;
+    RECT rcView;
 
-  TRACE("point %ld,%ld, direction %s\n", pt.x, pt.y,
-        (vkDirection == VK_DOWN) ? "VK_DOWN" :
-        ((vkDirection == VK_UP) ? "VK_UP" :
-        ((vkDirection == VK_LEFT) ? "VK_LEFT" : "VK_RIGHT")));
+    TRACE("point %ld,%ld, direction %s\n", pt.x, pt.y,
+          (vkDirection == VK_DOWN) ? "VK_DOWN" :
+          ((vkDirection == VK_UP) ? "VK_UP" :
+          ((vkDirection == VK_LEFT) ? "VK_LEFT" : "VK_RIGHT")));
 
-  if (LISTVIEW_GetViewRect(infoPtr, &rcView))
-  {
-    ZeroMemory(&lvIntHit, sizeof(lvIntHit));
-    LISTVIEW_GetOrigin(infoPtr, &lvIntHit.ht.pt);
+    if (!LISTVIEW_GetViewRect(infoPtr, &rcView)) return -1;
+    
+    if (!LISTVIEW_GetOrigin(infoPtr, &lvIntHit.ht.pt)) return -1;
+    
     lvIntHit.ht.pt.x += pt.x;
     lvIntHit.ht.pt.y += pt.y;
 
     if (vkDirection == VK_DOWN)
-      lvIntHit.ht.pt.y += infoPtr->nItemHeight;
+        lvIntHit.ht.pt.y += infoPtr->nItemHeight;
     else if (vkDirection == VK_UP)
-      lvIntHit.ht.pt.y -= infoPtr->nItemHeight;
+        lvIntHit.ht.pt.y -= infoPtr->nItemHeight;
     else if (vkDirection == VK_LEFT)
-      lvIntHit.ht.pt.x -= infoPtr->nItemWidth;
+        lvIntHit.ht.pt.x -= infoPtr->nItemWidth;
     else if (vkDirection == VK_RIGHT)
-      lvIntHit.ht.pt.x += infoPtr->nItemWidth;
-
-    if (!PtInRect(&rcView, lvIntHit.ht.pt))
-      return -1;
-    else
-    {
-      nItem = LISTVIEW_SuperHitTestItem(infoPtr, &lvIntHit, TRUE);
-      return nItem == -1 ? lvIntHit.iDistItem : nItem;
-    }
-  }
+        lvIntHit.ht.pt.x += infoPtr->nItemWidth;
 
-  return nItem;
+    if (!PtInRect(&rcView, lvIntHit.ht.pt)) return -1;
+    
+    nItem = LISTVIEW_SuperHitTestItem(infoPtr, &lvIntHit, TRUE);
+    return nItem == -1 ? lvIntHit.iDistItem : nItem;
 }
 
 /***
@@ -5120,8 +5153,7 @@
      *     information from the application
      */
 
-    TRACE("(lpLVItem=%s, internal=%d, isW=%d)\n",
-          debuglvitem_t(lpLVItem, isW), internal, isW);
+    TRACE("(lpLVItem=%s, internal=%d, isW=%d)\n", debuglvitem_t(lpLVItem, isW), internal, isW);
 
     if (!lpLVItem || (lpLVItem->iItem < 0) ||
         (lpLVItem->iItem >= GETITEMCOUNT(infoPtr)))
@@ -5313,19 +5345,17 @@
  */
 static BOOL LISTVIEW_GetItemBoundBox(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lpRect)
 {
-  BOOL bResult = FALSE;
+    BOOL bResult;
 
-  TRACE("(nItem=%d,lpRect=%p)\n", nItem, lpRect);
+    TRACE("(nItem=%d,lpRect=%p)\n", nItem, lpRect);
 
-  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) &&
-      (lpRect != NULL))
-  {
-      bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL,
-				      lpRect, NULL, NULL, NULL);
-  }
-  TRACE("result %s: (%d,%d)-(%d,%d)\n", bResult ? "TRUE" : "FALSE",
-	lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
-  return bResult;
+    if (!lpRect) return FALSE;
+	  
+    bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, 0, 0, lpRect, 0, 0, 0);
+
+    TRACE("result %s: (%d,%d)-(%d,%d)\n", bResult ? "TRUE" : "FALSE",
+	  lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
+    return bResult;
 }
 
 /***
@@ -5345,19 +5375,18 @@
  */
 static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, LPPOINT lpptPosition)
 {
-  BOOL bResult = FALSE;
+    BOOL bResult;
 
-  TRACE("(nItem=%d, lpptPosition=%p)\n", nItem, lpptPosition);
+    TRACE("(nItem=%d, lpptPosition=%p)\n", nItem, lpptPosition);
 
-  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) &&
-      (lpptPosition != NULL))
-  {
-    bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, lpptPosition,
+    if(!lpptPosition) return FALSE;
+  
+    bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, NULL, lpptPosition,
 				    NULL, NULL, NULL, NULL);
+    
     TRACE("result %s (%ld,%ld)\n", bResult ? "TRUE" : "FALSE",
           lpptPosition->x, lpptPosition->y);
-   }
-   return bResult;
+     return bResult;
 }
 
 /***
@@ -5555,7 +5584,6 @@
   {
     LVITEMW lvItem;
 
-    ZeroMemory(&lvItem, sizeof(lvItem));
     lvItem.mask = LVIF_INDENT;
     lvItem.iItem = nItem;
     lvItem.iSubItem = 0;
@@ -5575,8 +5603,7 @@
       switch(lprc->left)
       {
       case LVIR_ICON:
-	bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL,
-					NULL, lprc, NULL, NULL);
+	bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, 0, 0, 0, lprc, 0, 0);
 	if (uView & LVS_REPORT)
 	{
             lprc->left += nIndent;
@@ -5587,8 +5614,7 @@
       case LVIR_LABEL:
 	if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
         {
-          bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL,
-					  NULL, NULL, lprc, NULL);
+	  bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, 0, 0, 0, 0, lprc, 0);
         }
         else
         {
@@ -5628,13 +5654,13 @@
         {
 	  RECT label_rect, icon_rect;
 
-	  bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL,
+	  bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, NULL, NULL,
 					  NULL, &icon_rect, &label_rect, NULL);
 	  UnionRect (lprc, &icon_rect, &label_rect);
         }
         else
         {
-	  if (!LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL,
+	  if (!LISTVIEW_GetAllMeasures(infoPtr, nItem, NULL, NULL,
 				     lprc, NULL, NULL, NULL)) break;
           bResult = TRUE;
           if (!(infoPtr->dwExStyle&LVS_EX_FULLROWSELECT) && uView&LVS_REPORT)
@@ -5895,20 +5921,13 @@
  */
 static LRESULT LISTVIEW_GetItemTextT(LISTVIEW_INFO *infoPtr, INT nItem, LPLVITEMW lpLVItem, BOOL isW)
 {
-  INT nLength = 0;
+    if (!lpLVItem || (nItem < 0) || (nItem >= GETITEMCOUNT(infoPtr))) return 0;
 
-  if (lpLVItem != NULL)
-  {
-    if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)))
-    {
-      lpLVItem->mask = LVIF_TEXT;
-      lpLVItem->iItem = nItem;
-      if (LISTVIEW_GetItemT(infoPtr, lpLVItem, FALSE, isW))
-        nLength = textlenT(lpLVItem->pszText, isW);
-    }
-  }
+    lpLVItem->mask = LVIF_TEXT;
+    lpLVItem->iItem = nItem;
+    if (!LISTVIEW_GetItemT(infoPtr, lpLVItem, FALSE, isW)) return 0;
 
-  return nLength;
+    return textlenT(lpLVItem->pszText, isW);
 }
 
 /***
@@ -6076,8 +6095,7 @@
 {
     if (!lpptOrigin) return FALSE;
 
-    LISTVIEW_GetAllMeasure(infoPtr, -1, lpptOrigin, NULL,
-			  NULL, NULL, NULL, NULL);
+    LISTVIEW_GetAllMeasures(infoPtr, -1, lpptOrigin, 0, 0, 0, 0, 0);
 
     TRACE("(pt=(%ld,%ld))\n", lpptOrigin->x, lpptOrigin->y);
 
@@ -6196,6 +6214,7 @@
 
   TRACE("(x=%ld, y=%ld)\n", lpInt->ht.pt.x, lpInt->ht.pt.y);
 
+  /* FIXME: get the visible range */
   topindex = LISTVIEW_GetTopIndex(infoPtr);
   if (uView == LVS_REPORT)
   {
@@ -6327,29 +6346,25 @@
  */
 static LRESULT LISTVIEW_HitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpHitTestInfo)
 {
-  INT nItem = -1;
+    lpHitTestInfo->flags = 0;
 
-  lpHitTestInfo->flags = 0;
-
-  if (infoPtr->rcList.left > lpHitTestInfo->pt.x)
-    lpHitTestInfo->flags = LVHT_TOLEFT;
-  else if (infoPtr->rcList.right < lpHitTestInfo->pt.x)
-    lpHitTestInfo->flags = LVHT_TORIGHT;
-  if (infoPtr->rcList.top > lpHitTestInfo->pt.y)
-    lpHitTestInfo->flags |= LVHT_ABOVE;
-  else if (infoPtr->rcList.bottom < lpHitTestInfo->pt.y)
-    lpHitTestInfo->flags |= LVHT_BELOW;
+    if (infoPtr->rcList.left > lpHitTestInfo->pt.x)
+	lpHitTestInfo->flags = LVHT_TOLEFT;
+    else if (infoPtr->rcList.right < lpHitTestInfo->pt.x)
+	lpHitTestInfo->flags = LVHT_TORIGHT;
+    
+    if (infoPtr->rcList.top > lpHitTestInfo->pt.y)
+	lpHitTestInfo->flags |= LVHT_ABOVE;
+    else if (infoPtr->rcList.bottom < lpHitTestInfo->pt.y)
+	lpHitTestInfo->flags |= LVHT_BELOW;
 
-  if (lpHitTestInfo->flags == 0)
-  {
+    if (lpHitTestInfo->flags) return -1;
+    
     /* NOTE (mm 20001022): We must not allow iSubItem to be touched, for
      * an app might pass only a structure with space up to iItem!
      * (MS Office 97 does that for instance in the file open dialog)
      */
-    nItem = LISTVIEW_HitTestItem(infoPtr, lpHitTestInfo, FALSE);
-  }
-
-  return nItem;
+    return LISTVIEW_HitTestItem(infoPtr, lpHitTestInfo, FALSE);
 }
 
 /***
@@ -6404,7 +6419,7 @@
   INT nNewColumn = -1;
   HDITEMW hdi;
 
-  TRACE("(nColumn=%d, lpColumn=%p)\n", nColumn, lpColumn);
+  TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW);
 
   if (lpColumn != NULL)
   {
@@ -6557,7 +6572,7 @@
  *
  * PARAMETER(S):
  * [I] infoPtr : valid pointer to the listview structure
- * [I] LPLVITEMW : item information
+ * [I] lpLVItem : item information
  * [I] isW : TRUE if lpLVItem is Unicode, FALSE if it's ANSI
  *
  * RETURN:
@@ -6599,6 +6614,11 @@
     is_sorted = (lStyle & (LVS_SORTASCENDING | LVS_SORTDESCENDING)) &&
 	        !(lStyle & LVS_OWNERDRAWFIXED) && (LPSTR_TEXTCALLBACKW != lpLVItem->pszText);
 
+    nItem = DPA_InsertPtr( infoPtr->hdpaItems, 
+		           is_sorted ? GETITEMCOUNT( infoPtr ) + 1 : lpLVItem->iItem, 
+			   hdpaSubItems );
+    if (nItem == -1) goto fail;
+   
     if (!LISTVIEW_SetItemT(infoPtr, lpLVItem, isW)) goto fail;
 
     /* if we're sorted, sort the list, and update the index */
@@ -6606,17 +6626,17 @@
     {
 	DPA_Sort( infoPtr->hdpaItems, LISTVIEW_InsertCompare, (LPARAM)infoPtr->hwndSelf );
 	nItem = DPA_GetPtrIndex( infoPtr->hdpaItems, hdpaSubItems );
-	if (nItem == -1) goto fail;
+	if (nItem == -1)
+	{
+	    ERR("We can't find the item we just inserted, possible memory corruption.");
+	    /* we can't remove it from the list if we can't find it, so just fail */
+	    goto fail;
+	}
     }
 
     /* Add the subitem list to the items array. Do this last in case we go to
      * fail during the above.
      */
-    nItem = DPA_InsertPtr( infoPtr->hdpaItems, 
-		           is_sorted ? GETITEMCOUNT( infoPtr ) + 1 : lpLVItem->iItem, 
-			   hdpaSubItems );
-    if (nItem == -1) goto fail;
-   
     LISTVIEW_ShiftIndices(infoPtr, nItem, 1);
     
     lpItem->valid = TRUE;
@@ -6639,9 +6659,11 @@
     /* FIXME: refresh client area */
     LISTVIEW_Invalidate(infoPtr);
 
+    TRACE("    <- %d\n", nItem);
     return nItem;
 
 fail:
+    DPA_DeletePtr(hdpaSubItems, 0);
     DPA_Destroy (hdpaSubItems);
     COMCTL32_Free (lpItem);
     return -1;
@@ -7853,6 +7875,9 @@
     /* now we can scroll the list */
     ScrollWindowEx(infoPtr->hwndSelf, dx, dy, &infoPtr->rcList, 
 		   &infoPtr->rcList, 0, 0, SW_INVALIDATE);
+    /* if we have focus, adjust rect */
+    if (infoPtr->bFocus && !IsRectEmpty(&infoPtr->rcFocus))
+	OffsetRect(&infoPtr->rcFocus, dx, dy);
     UpdateWindow(infoPtr->hwndSelf);
 }
 




More information about the wine-patches mailing list