Listview M14

Dimitrie O. Paun dpaun at rogers.com
Wed Oct 9 17:11:28 CDT 2002


ChangeLog
  Narrow down the items we iterate over in LIST, and REPORT mode
  Fix a Client --> List coordinate transformations in FindItem
  Fix bug in HitItem (in LIST and REPORT mode)
  Avoid the last bit of drawing in REPORT mode.

--- dlls/comctl32/listview.c.M13	Wed Oct  9 18:02:04 2002
+++ dlls/comctl32/listview.c	Wed Oct  9 18:05:13 2002
@@ -770,27 +770,47 @@
 static BOOL iterator_frameditems(ITERATOR* i, LISTVIEW_INFO* infoPtr, const RECT* lprc)
 {
     UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
-    INT nPerCol, nPerRow;
+    INT lower, upper;
+    RECT frame = *lprc;
+    POINT Origin;
     
     /* in case we fail, we want to return an empty iterator */
     if (!iterator_empty(i)) return FALSE;
 
+    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;
+
+    OffsetRect(&frame, -Origin.x, -Origin.y);
+
     if (uView == LVS_ICON || uView == LVS_SMALLICON)
     {
+	/* FIXME: we got to do better then this */
 	i->range.lower = 0;
 	i->range.upper = infoPtr->nItemCount - 1;
 	return TRUE;
     }
-    
-    i->range.lower = LISTVIEW_GetTopIndex(infoPtr);
-    
-    nPerCol = max((infoPtr->rcList.bottom - infoPtr->rcList.top) / infoPtr->nItemHeight, 1) + 1;
-    if (uView == LVS_REPORT)
-	nPerRow = 1;
-    else /* uView == LVS_LIST */
-	nPerRow = max((infoPtr->rcList.right - infoPtr->rcList.left)/infoPtr->nItemWidth, 1);
+    else if (uView == LVS_REPORT)
+    {
+	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;
+    }
+    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;
+    }
 
-    i->range.upper = min(i->range.lower + nPerCol * nPerRow, infoPtr->nItemCount - 1);
+    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;
 }
 
@@ -3474,9 +3494,9 @@
     /* we now narrow the columns as well */
     nLastCol = nColumnCount - 1;
     for(nFirstCol = 0; nFirstCol < nColumnCount; nFirstCol++)
-	if (lpCols[nFirstCol].rc.right + ptOrig.x >= rcClip.left) break;
+	if (lpCols[nFirstCol].rc.right >= rcClip.left) break;
     for(nLastCol = nColumnCount - 1; nLastCol >= 0; nLastCol--)
-	if (lpCols[nLastCol].rc.left + ptOrig.x < rcClip.right) break;
+	if (lpCols[nLastCol].rc.left < rcClip.right) break;
 
     /* cache the per-column information before we start drawing */
     for (j = nFirstCol; j <= nLastCol; j++)
@@ -3539,10 +3559,6 @@
     	isFocused = FALSE;	    
 	for (j = nFirstCol; j <= nLastCol; j++)
 	{
-	    if (cdmode & CDRF_NOTIFYITEMDRAW)
-		cditemmode = notify_customdrawitem (infoPtr, hdc, i.nItem, j, CDDS_ITEMPREPAINT);
-	    if (cditemmode & CDRF_SKIPDEFAULT) continue;
-
 	    rcItem = lpCols[j].rc;
 	    rcItem.left += REPORT_MARGINX;
 	    rcItem.right = max(rcItem.left, rcItem.right - REPORT_MARGINX);
@@ -3552,6 +3568,12 @@
 	    /* Offset the Scroll Bar Pos */
 	    OffsetRect(&rcItem, ptOrig.x, ptOrig.y);
 
+	    if (rgntype == COMPLEXREGION && !RectVisible(hdc, &rcItem)) continue;
+
+	    if (cdmode & CDRF_NOTIFYITEMDRAW)
+		cditemmode = notify_customdrawitem (infoPtr, hdc, i.nItem, j, CDDS_ITEMPREPAINT);
+	    if (cditemmode & CDRF_SKIPDEFAULT) continue;
+
 	    if (j == 0)
 		isFocused = LISTVIEW_DrawItem(infoPtr, hdc, i.nItem, rcItem);
 	    else
@@ -4415,8 +4437,8 @@
 	
 	FIXME("LVFI_NEARESTXY is slow.\n");
         if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return -1;
-	Destination.x = lpFindInfo->pt.x + Origin.x;
-	Destination.y = lpFindInfo->pt.y + Origin.y;
+	Destination.x = lpFindInfo->pt.x - Origin.x;
+	Destination.y = lpFindInfo->pt.y - Origin.y;
 	switch(lpFindInfo->vkDirection)
 	{
 	case VK_DOWN:  Destination.y += infoPtr->nItemHeight; break;
@@ -5622,15 +5644,16 @@
 	else
 	{
 	    POINT Origin, Position;
+	    INT nPerCol = LISTVIEW_GetCountPerColumn(infoPtr);
 
 	    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return -1;
 	    Position.x = lpht->pt.x - Origin.x;
 	    Position.y = lpht->pt.y - Origin.y;
 
-	    if (Position.x < LISTVIEW_GetCountPerRow(infoPtr) * infoPtr->nItemWidth &&
-	        Position.y < LISTVIEW_GetCountPerColumn(infoPtr) * infoPtr->nItemHeight)
+	    if (Position.y < nPerCol * infoPtr->nItemHeight)
 	    {
-		lpht->iItem = (Position.x / infoPtr->nItemWidth) * (Position.y / infoPtr->nItemHeight);
+		lpht->iItem = (Position.x / infoPtr->nItemWidth) * nPerCol + (Position.y / infoPtr->nItemHeight);
+		if (lpht->iItem < 0 || lpht->iItem >= infoPtr->nItemCount) lpht->iItem = -1;
 	    }
 	}
     }




More information about the wine-patches mailing list