Listview Q2

Dimitrie O. Paun dpaun at rogers.com
Mon Oct 14 18:38:04 CDT 2002


ChangeLog
  Fix iterator creation for LVS_LIST mode
  Use assert() instead of hand-made hack.

--- dlls/comctl32/listview.c.Q1	Mon Oct 14 13:58:02 2002
+++ dlls/comctl32/listview.c	Mon Oct 14 19:36:27 2002
@@ -59,6 +59,7 @@
 #include "config.h"
 #include "wine/port.h"
 
+#include <assert.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
@@ -883,7 +884,6 @@
 {
     UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
     RECT frame = *lprc, rcItem, rcTemp;
-    INT lower, upper, nItem;
     POINT Origin;
     
     /* in case we fail, we want to return an empty iterator */
@@ -895,6 +895,8 @@
 
     if (uView == LVS_ICON || uView == LVS_SMALLICON)
     {
+	INT nItem;
+	
 	if (uView == LVS_ICON)
 	{
 	    if (LISTVIEW_GetItemBox(infoPtr, infoPtr->nFocusedItem, &rcItem) && IntersectRect(&rcTemp, &rcItem, lprc))
@@ -918,27 +920,44 @@
     }
     else if (uView == LVS_REPORT)
     {
+	INT lower, upper;
+	
 	if (frame.left >= infoPtr->nItemWidth) return TRUE;
 	if (frame.top >= infoPtr->nItemHeight * infoPtr->nItemCount) return TRUE;
 	
-	lower = frame.top / infoPtr->nItemHeight;
-	upper = (frame.bottom - 1) / infoPtr->nItemHeight;
+	lower = max(frame.top / infoPtr->nItemHeight, 0);
+	upper = min((frame.bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1);
+	if (upper < lower) return TRUE;
+	i->range.lower = lower;
+	i->range.upper = upper;
     }
     else
     {
 	INT nPerCol = max((infoPtr->rcList.bottom - infoPtr->rcList.top) / infoPtr->nItemHeight, 1);
-	if (frame.top >= infoPtr->nItemHeight * nPerCol) return TRUE;
-	lower = (frame.left / infoPtr->nItemWidth) * nPerCol + frame.top / infoPtr->nItemHeight;
-	upper = ((frame.right - 1) / infoPtr->nItemWidth) * nPerCol + (frame.bottom - 1) / infoPtr->nItemHeight;
+	INT nFirstRow = max(frame.top / infoPtr->nItemHeight, 0);
+	INT nLastRow = min((frame.bottom - 1) / infoPtr->nItemHeight, nPerCol - 1);
+	INT nFirstCol = max(frame.left / infoPtr->nItemWidth, 0);
+	INT nLastCol = min((frame.right - 1) / infoPtr->nItemWidth, (infoPtr->nItemCount + nPerCol - 1) / nPerCol);
+	INT lower = nFirstCol * nPerCol + nFirstRow;
+	RANGE item_range;
+	INT nCol;
+
+	TRACE("nPerCol=%d, nFirstRow=%d, nLastRow=%d, nFirstCol=%d, nLastCol=%d, lower=%d\n",
+	      nPerCol, nFirstRow, nLastRow, nFirstCol, nLastCol, lower);
+	
+	if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE;
+
+	if (!(i->ranges = DPA_Create(nLastCol - nFirstCol + 1))) return FALSE;
+	for (nCol = nFirstCol; nCol < nLastCol; nCol++)
+	{
+	    item_range.lower = nCol * nPerCol + nFirstRow;
+	    if(item_range.lower >= infoPtr->nItemCount) break;
+	    item_range.upper = min(nCol * nPerCol + nLastRow, infoPtr->nItemCount - 1);
+	    TRACE("   range=[%d,%d]\n", item_range.lower, item_range.upper);
+	    ranges_add(i->ranges, item_range);
+	}
     }
 
-    if (upper < 0 || lower >= infoPtr->nItemCount) return TRUE;
-    lower = max(lower, 0);
-    upper = min(upper, infoPtr->nItemCount - 1);
-    if (upper < lower) return TRUE;
-    i->range.lower = lower;
-    i->range.upper = upper;
-    
     return TRUE;
 }
 
@@ -1560,11 +1579,8 @@
     }
     if (uView == LVS_ICON && (lprcBox || lprcBounds || lprcLabel))
     {
-	if (!(lpLVItem->mask & LVIF_STATE) || 
-	    !(lpLVItem->stateMask & LVIS_FOCUSED)) 
-	    goto fail;
-	if (lpLVItem->state & LVIS_FOCUSED)
-	    oversizedBox = doLabel = TRUE;
+	assert((lpLVItem->mask & LVIF_STATE) && (lpLVItem->stateMask & LVIS_FOCUSED));
+	if (lpLVItem->state & LVIS_FOCUSED) oversizedBox = doLabel = TRUE;
     }
     if (lprcLabel) doLabel = TRUE;
     if (doLabel || lprcIcon) doIcon = TRUE;
@@ -1593,7 +1609,7 @@
 	else
 	{
 	    /* we need the ident in report mode, if we don't have it, we fail */
-	    if (uView == LVS_REPORT && !(lpLVItem->mask & LVIF_INDENT)) goto fail;
+	    assert(uView != LVS_REPORT || (lpLVItem->mask & LVIF_INDENT));
 	    State.left = Box.left;
 	    if (uView == LVS_REPORT) State.left += infoPtr->iconSize.cx * lpLVItem->iIndent;
 	    State.top  = Box.top;
@@ -1655,7 +1671,7 @@
 	   goto calc_label;
 	}
 	/* we need the text in non owner draw mode */
-	if (!(lpLVItem->mask & LVIF_TEXT)) goto fail;
+	assert(lpLVItem->mask & LVIF_TEXT);
 	if (is_textT(lpLVItem->pszText, TRUE))
         {
     	    HFONT hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
@@ -1740,11 +1756,6 @@
     TRACE("    - box=%s\n", debugrect(&Box));
 
     return TRUE;
-
-fail:
-    ERR("Incorrect item=%s; please report.\n", debuglvitem_t(lpLVItem, TRUE));
-    *((char *)0) = 0;   /* it's an internal function, should never happen */
-    return FALSE;
 }
 
 /***




More information about the wine-patches mailing list