[patch] Support for LVM_SUBITEMHITTEST

Paul Rupe prupe at myrealbox.com
Sun Jun 9 17:41:16 CDT 2002


This patch handles the LVM_SUBITEMHITTEST message for Listviews and 
fixes an infinite loop in Xnews' group window.


Changelog:
   dlls/comctl32/listview.c
   Paul Rupe <prupe at myrealbox.com>
   Support for LVM_SUBITEMHITTEST; check for out-of-bounds subitem index
   in LISTVIEW_GetSubItemRect


-- 
Paul Rupe                                        "She smiled, in the 
end."
p r u p e @ m y r e a l b o x . c o m

| Oppose government police-ware on your PC!
| Stop the Consumer Broadband and Digital Television Promotion Act!
| <http://www.eff.org/alerts/20020322_eff_cbdtpa_alert.html>
-------------- next part --------------
Index: dlls/comctl32/listview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/listview.c,v
retrieving revision 1.129
diff -u -r1.129 listview.c
--- dlls/comctl32/listview.c	31 May 2002 23:25:44 -0000	1.129
+++ dlls/comctl32/listview.c	9 Jun 2002 22:03:02 -0000
@@ -6081,17 +6081,15 @@
     }
     else
     {
+        int top = min(((LISTVIEW_INFO *)GetWindowLongW(hwnd, 0))->nColumnCount,
+                      nSubItem - 1);
+
         LISTVIEW_GetItemRect(hwnd,nItem,lprc);
-        count = 0;
-        while (count<(nSubItem-1))
-        {
+        for (count = 0; count < top; count++)
             lprc->left += LISTVIEW_GetColumnWidth(hwnd,count);
-            count ++;
-        }
 
         lprc->right = LISTVIEW_GetColumnWidth(hwnd,(nSubItem-1)) +
                             lprc->left;
-
     }
     return TRUE;
 }
@@ -6549,8 +6547,8 @@
   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(hwnd, 0);
   LONG lStyle = GetWindowLongW(hwnd, GWL_STYLE);
   UINT uView = lStyle & LVS_TYPEMASK;
-  INT i,topindex,bottomindex;
-  RECT rcItem;
+  INT i,j,topindex,bottomindex;
+  RECT rcItem,rcSubItem;
   DWORD xterm, yterm, dist;
 
   TRACE("(hwnd=%x, x=%ld, y=%ld)\n", hwnd, lpInt->ht.pt.x, lpInt->ht.pt.y);
@@ -6576,6 +6574,7 @@
     {
       if (PtInRect(&rcItem, lpInt->ht.pt))
       {
+        rcSubItem = rcItem;
         rcItem.left = LVIR_ICON;
         if (LISTVIEW_GetItemRect(hwnd, i, &rcItem))
         {
@@ -6583,8 +6582,7 @@
           {
             lpInt->ht.flags = LVHT_ONITEMICON;
             lpInt->ht.iItem = i;
-            if (subitem) lpInt->ht.iSubItem = 0;
-            return i;
+            goto set_subitem;
           }
         }
 
@@ -6595,14 +6593,28 @@
           {
             lpInt->ht.flags = LVHT_ONITEMLABEL;
             lpInt->ht.iItem = i;
-            if (subitem) lpInt->ht.iSubItem = 0;
-            return i;
+            goto set_subitem;
           }
         }
 
         lpInt->ht.flags = LVHT_ONITEMSTATEICON;
         lpInt->ht.iItem = i;
-        if (subitem) lpInt->ht.iSubItem = 0;
+       set_subitem:
+        if (subitem)
+        {
+          lpInt->ht.iSubItem = 0;
+          rcSubItem.right = rcSubItem.left;
+          for (j = 0; j < infoPtr->nColumnCount; j++)
+          {
+            rcSubItem.left = rcSubItem.right;
+            rcSubItem.right += LISTVIEW_GetColumnWidth(hwnd, j);
+            if (PtInRect(&rcSubItem, lpInt->ht.pt))
+            {
+              lpInt->ht.iSubItem = j;
+              break;
+            }
+          }
+        }
         return i;
       }
       else
@@ -6699,6 +6711,40 @@
 
 /***
  * DESCRIPTION:
+ * Determines which listview subitem is located at the specified position.
+ *
+ * PARAMETER(S):
+ * [I] HWND : window handle
+ * [IO} LPLVHITTESTINFO : hit test information
+ *
+ * RETURN:
+ *   SUCCESS : item index
+ *   FAILURE : -1
+ */
+static LRESULT LISTVIEW_SubItemHitTest(HWND hwnd, LPLVHITTESTINFO lpHitTestInfo)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(hwnd, 0);
+  INT nItem = -1;
+
+  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 (lpHitTestInfo->flags == 0)
+    nItem = LISTVIEW_HitTestItem(hwnd, lpHitTestInfo, TRUE);
+
+  return nItem;
+}
+
+/***
+ * DESCRIPTION:
  * Inserts a new column.
  *
  * PARAMETER(S):
@@ -9644,7 +9690,8 @@
   case LVM_SORTITEMS:
     return LISTVIEW_SortItems(hwnd, (PFNLVCOMPARE)lParam, (LPARAM)wParam);
 
-/*	case LVM_SUBITEMHITTEST: */
+  case LVM_SUBITEMHITTEST:
+    return LISTVIEW_SubItemHitTest(hwnd, (LPLVHITTESTINFO)lParam);
 
   case LVM_UPDATE:
     return LISTVIEW_Update(hwnd, (INT)wParam);


More information about the wine-patches mailing list