some listview fixes

Aric Stewart aric at codeweavers.com
Sun May 12 20:45:08 CDT 2002


These fixes make WinMX (my favorite windows fileshareing program) behave.

The problem was that the program called SetItemState during the Custom 
Draw phase of items. SetItemState results in an Invalidate Rect which 
causes an Infinite redraw loop. So do not invalidate the rect while 
drawing.

Additionally implement GetSubItemRect and a quick change to 
notifications sent for OwnerData items.

-aric
-------------- next part --------------
Index: dlls/comctl32/listview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/listview.c,v
retrieving revision 1.126
diff -w -u -r1.126 listview.c
--- dlls/comctl32/listview.c	11 Apr 2002 17:31:45 -0000	1.126
+++ dlls/comctl32/listview.c	13 May 2002 01:45:43 -0000
@@ -158,6 +158,7 @@
   WPARAM charCode;             /* Added */
   INT nSearchParamLength;      /* Added */
   WCHAR szSearchParam[ MAX_PATH ]; /* Added */
+  BOOL bIsDrawing;
 } LISTVIEW_INFO;
 
 /*
@@ -236,6 +237,7 @@
 static BOOL LISTVIEW_GetItemBoundBox(HWND, INT, LPRECT);
 static BOOL LISTVIEW_GetItemPosition(HWND, INT, LPPOINT);
 static LRESULT LISTVIEW_GetItemRect(HWND, INT, LPRECT);
+static LRESULT LISTVIEW_GetSubItemRect(HWND, INT, INT, INT, LPRECT);
 static INT LISTVIEW_GetItemWidth(HWND);
 static INT LISTVIEW_GetLabelWidth(HWND, INT);
 static LRESULT LISTVIEW_GetOrigin(HWND, LPPOINT);
@@ -2746,9 +2748,10 @@
       if ((itm.state & lpLVItem->stateMask) != 
           (lpLVItem->state & lpLVItem->stateMask))
       {
-        /* send LVN_ITEMCHANGING notification */
-        if (!listview_notify(hwnd, LVN_ITEMCHANGING, &nmlv))
-        {
+        /* 
+         * As per MSDN LVN_ITEMCHANGING notifications are _NOT_ sent
+         * by LVS_OWERNDATA list controls
+         */
           if (lpLVItem->stateMask & LVIS_FOCUSED)
           {
             if (lpLVItem->state & LVIS_FOCUSED)
@@ -2772,9 +2775,9 @@
 
 	  rcItem.left = LVIR_BOUNDS;
 	  LISTVIEW_GetItemRect(hwnd, lpLVItem->iItem, &rcItem);
+      if (!infoPtr->bIsDrawing)
 	  InvalidateRect(hwnd, &rcItem, TRUE);
         }
-      }
       return TRUE;
     }
     return FALSE;
@@ -2863,6 +2866,7 @@
           {
             rcItem.left = LVIR_BOUNDS;
 	    LISTVIEW_GetItemRect(hwnd, lpLVItem->iItem, &rcItem);
+           if (!infoPtr->bIsDrawing)
             InvalidateRect(hwnd, &rcItem, TRUE);
           }
         }
@@ -3910,6 +3914,7 @@
   DWORD cdmode;
   RECT rect;
 
+  infoPtr->bIsDrawing = TRUE;
   LISTVIEW_DumpListview (infoPtr, __LINE__);
 
   GetClientRect(hwnd, &rect);
@@ -3945,6 +3950,8 @@
  
   if (cdmode & CDRF_NOTIFYPOSTPAINT)
       LISTVIEW_SendCustomDrawNotify(hwnd, CDDS_POSTPAINT, hdc, rect);
+
+  infoPtr->bIsDrawing = FALSE;
 }
 
 
@@ -6050,6 +6057,42 @@
   return bResult;
 }
 
+
+static LRESULT LISTVIEW_GetSubItemRect(HWND hwnd, INT nItem, INT nSubItem, INT
+flags, LPRECT lprc)
+{
+    UINT uView = GetWindowLongW(hwnd, GWL_STYLE) & LVS_TYPEMASK;
+    INT  count;
+
+    TRACE("(hwnd=%x, nItem=%d, nSubItem=%d lprc=%p)\n", hwnd, nItem, nSubItem, 
+            lprc);
+
+    if (!(uView & LVS_REPORT))
+        return FALSE;
+
+    if (flags & LVIR_ICON)
+    {
+        FIXME("Unimplemented LVIR_ICON\n");
+        return FALSE;
+    }
+    else
+    {
+        LISTVIEW_GetItemRect(hwnd,nItem,lprc);
+        count = 0;
+        while (count<(nSubItem-1))
+        {
+            lprc->left += LISTVIEW_GetColumnWidth(hwnd,count);
+            count ++;
+        }
+
+        lprc->right = LISTVIEW_GetColumnWidth(hwnd,(nSubItem-1)) +
+                            lprc->left;
+
+    }
+    return TRUE;    
+}
+
+
 /***
  * DESCRIPTION:
  * Retrieves the width of a label.
@@ -8000,6 +8043,7 @@
   infoPtr->hwndEdit = 0;
   infoPtr->pedititem = NULL;
   infoPtr->nEditLabelItem = -1;
+  infoPtr->bIsDrawing = FALSE;
 
   /* get default font (icon title) */
   SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
@@ -9469,8 +9513,8 @@
     return LISTVIEW_GetStringWidthT(hwnd, (LPCWSTR)lParam, TRUE);
     
   case LVM_GETSUBITEMRECT:
-    FIXME("LVM_GETSUBITEMRECT: unimplemented\n");
-    return FALSE;
+    return LISTVIEW_GetSubItemRect(hwnd, (UINT)wParam, ((LPRECT)lParam)->top,
+                                   ((LPRECT)lParam)->left, (LPRECT)lParam);
 
   case LVM_GETTEXTBKCOLOR:
     return LISTVIEW_GetTextBkColor(hwnd);


More information about the wine-patches mailing list