Listview M11

Dimitrie O. Paun dpaun at rogers.com
Wed Oct 9 08:44:21 CDT 2002


ChangeLog
  Rewrite HitTest to make it pretty, and very fast.

--- dlls/comctl32/listview.c.M10	Wed Oct  9 03:16:07 2002
+++ dlls/comctl32/listview.c	Wed Oct  9 09:40:53 2002
@@ -5695,12 +5695,20 @@
  * [IO] lpht : hit test information
  * [I] subitem : fill out iSubItem.
  *
+ * 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)
+ * 
  * RETURN:
  *   SUCCESS : item index
  *   FAILURE : -1
  */
 static LRESULT LISTVIEW_HitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpht, BOOL subitem)
 {
+    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
+    RECT rcBounds, rcIcon, rcLabel;
+    
     TRACE("(x=%ld, y=%ld)\n", lpht->pt.x, lpht->pt.y);
     
     lpht->flags = 0;
@@ -5718,12 +5726,113 @@
 	lpht->flags |= LVHT_BELOW;
 
     if (lpht->flags) return -1;
+
+    lpht->flags |= LVHT_NOWHERE;
+   
+    /* first deal with the large items */
+    if (uView == LVS_ICON && (infoPtr->dwStyle & LVS_OWNERDRAWFIXED) &&
+	PtInRect (&infoPtr->rcFocus, lpht->pt))
+    {
+	lpht->iItem = infoPtr->nFocusedItem;
+    }
+    else
+    {
+	if (uView == LVS_ICON || uView == LVS_SMALLICON)
+	{
+	    RECT rcSearch;
+	    ITERATOR i;
+
+	    rcSearch.left = lpht->pt.x - infoPtr->nItemWidth;
+	    rcSearch.top = lpht->pt.y - infoPtr->nItemHeight;
+	    rcSearch.right = lpht->pt.x + 1;
+	    rcSearch.bottom = lpht->pt.y + 1;
+
+	    iterator_create_frameditems(&i, infoPtr, &rcSearch, 0);
+	    while(iterator_next(&i))
+	    {
+		if (!LISTVIEW_GetItemMeasures(infoPtr, i.nItem, &rcBounds, 0, 0, 0)) continue;
+		if (PtInRect(&rcBounds, lpht->pt)) break;
+	    }
+	    lpht->iItem = i.nItem;
+	    iterator_destroy(&i);
+	}
+	else
+	{
+	    POINT Origin, Position;
+
+	    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)
+	    {
+		lpht->iItem = (Position.x / infoPtr->nItemWidth) * (Position.y / infoPtr->nItemHeight);
+	    }
+	}
+    }
+   
+    if (lpht->iItem == -1) return -1;
+
+    if (!LISTVIEW_GetItemMeasures(infoPtr, lpht->iItem, 0, &rcBounds, &rcIcon, &rcLabel)) return -1;
+    
+    if (!PtInRect(&rcBounds, lpht->pt)) return -1;
+
+    if (PtInRect(&rcIcon, lpht->pt))
+	lpht->flags |= LVHT_ONITEMICON;
+    else if (PtInRect(&rcLabel, lpht->pt))
+	lpht->flags |= LVHT_ONITEMLABEL;
+    else if (infoPtr->himlState)
+    {
+	/* FIXME: move this to GetItemMeasures */
+	LVITEMW lvItem;
+
+	lvItem.mask = LVIF_STATE;
+	lvItem.stateMask = LVIS_STATEIMAGEMASK;
+	lvItem.iItem = lpht->iItem;
+	lvItem.iSubItem = 0;
+	if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return -1;
+	{
+            UINT uStateImage = (lvItem.state & LVIS_STATEIMAGEMASK) >> 12;
+	    RECT rcState;
+
+	    if (uView == LVS_ICON)
+	    {
+     		rcState.left = rcIcon.left - infoPtr->iconStateSize.cx + 10;
+		rcState.top = rcIcon.top + infoPtr->iconSize.cy - infoPtr->iconStateSize.cy + 4;
+	    }
+	    else
+	    {
+		rcState.left = rcIcon.left - infoPtr->iconStateSize.cx - IMAGE_PADDING;
+		rcState.top = rcIcon.top;
+	    }
+	    rcState.right = rcState.left + infoPtr->iconStateSize.cx;
+	    rcState.bottom = rcState.top + infoPtr->iconStateSize.cy;
+	    
+ 	    if (uStateImage > 0 && PtInRect(&rcState, lpht->pt))
+		lpht->flags |= LVHT_ONITEMSTATEICON;
+	}
+    }
+    if (lpht->flags & LVHT_ONITEM)
+	lpht->flags &= ~LVHT_NOWHERE;
     
-    /* 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)
-     */
-    return LISTVIEW_SuperHitTestItem(infoPtr, lpht, subitem, FALSE);
+    if (uView == LVS_REPORT && lpht->iItem != -1 && subitem)
+    {
+  	INT j, nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
+        rcBounds.right = rcBounds.left;
+        for (j = 0; j < nColumnCount; j++)
+        {
+	    rcBounds.left = rcBounds.right;
+	    rcBounds.right += LISTVIEW_GetColumnWidth(infoPtr, j);
+	    if (PtInRect(&rcBounds, lpht->pt))
+	    {
+		lpht->iSubItem = j;
+		break;
+	    }
+	}
+    }
+
+    return lpht->iItem;
 }
 
 




More information about the wine-patches mailing list