[comctl32] more listview glitches

Felix Nawothnig felix.nawothnig at t-online.de
Thu Jun 2 23:24:57 CDT 2005


This patch fixes several missed invalidations occuring during 
column-resizing, reproducable as follows:

  - When shrinking a column as much pixels as resized stay white on the 
left-side of the column on the right-side (reproducable by draging the 
divider *fast* to the left or commenting out the TRACK[AW] cases).
  - Same glitch as above when the right-side column was scrolled out 
before (this is actually unrelated to the first glitch IIRC)
  - When the lv is scrolled right resizing the columns causes large 
parts (as much as scrolled) of it to stay white
  - When slowly (by 1px or so) enlarging a column with "foo..." 
(implicit ellipsis) in it causes it to become "fooW..." (I take 'W' as a 
"very wide char" here) the W isn't fully painted on the left side.

There is another glitch this patch doesn't fix: When the window is 
scrolled right and one shrinks a column an implicit scroll-left occurs 
which should invalidate the whole window (but doesn't). I'm not sure 
where to fix this so I'll first try to get this in.

ChangeLog:
Fix some missed invalidations after column-resize
-------------- next part --------------
Index: listview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/listview.c,v
retrieving revision 1.419
diff -u -r1.419 listview.c
--- listview.c	30 May 2005 11:10:01 -0000	1.419
+++ listview.c	3 Jun 2005 03:53:15 -0000
@@ -276,7 +276,8 @@
   HFONT hDefaultFont;
   HFONT hFont;
   INT ntmHeight;		/* Some cached metrics of the font used */
-  INT ntmAveCharWidth;		/* by the listview to draw items */
+  INT ntmMaxCharWidth;		/* by the listview to draw items */
+  INT nEllipsisWidth;
   BOOL bRedraw;  		/* Turns on/off repaints & invalidations */
   BOOL bAutoarrange;		/* Autoarrange flag when NOT in LVS_AUTOARRANGE */
   BOOL bFocus;
@@ -2492,12 +2493,17 @@
     HFONT hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
     HFONT hOldFont = SelectObject(hdc, hFont);
     TEXTMETRICW tm;
+    SIZE sz;
 
     if (GetTextMetricsW(hdc, &tm))
     {
 	infoPtr->ntmHeight = tm.tmHeight;
-	infoPtr->ntmAveCharWidth = tm.tmAveCharWidth;
+	infoPtr->ntmMaxCharWidth = tm.tmMaxCharWidth;
     }
+
+    if (GetTextExtentPoint32A(hdc, "...", 3, &sz))
+	infoPtr->nEllipsisWidth = sz.cx;
+	
     SelectObject(hdc, hOldFont);
     ReleaseDC(infoPtr->hwndSelf, hdc);
     
@@ -4269,6 +4275,7 @@
 {
     COLUMN_INFO *lpColumnInfo;
     RECT rcOld, rcCol;
+    POINT ptOrigin;
     INT nCol;
    
     if (nColumn < 0 || DPA_GetPtrCount(infoPtr->hdpaColumns) < 1) return;
@@ -4295,10 +4302,11 @@
     infoPtr->nItemWidth += dx;
 
     LISTVIEW_UpdateScroll(infoPtr);
+    LISTVIEW_GetOrigin(infoPtr, &ptOrigin);
 
     /* scroll to cover the deleted column, and invalidate for redraw */
     rcOld = infoPtr->rcList;
-    rcOld.left = rcCol.left;
+    rcOld.left = ptOrigin.x + rcCol.left + dx;
     ScrollWindowEx(infoPtr->hwndSelf, dx, 0, &rcOld, &rcOld, 0, 0, SW_ERASE | SW_INVALIDATE);
     
     /* we can restore focus now */
@@ -8286,21 +8294,27 @@
 	    dx = cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left);
 	    if (dx != 0)
 	    {
-		RECT rcCol = lpColumnInfo->rcHeader;
-
 		lpColumnInfo->rcHeader.right += dx;
 		LISTVIEW_ScrollColumns(infoPtr, lpnmh->iItem + 1, dx);
 		LISTVIEW_UpdateItemSize(infoPtr);
 		if (uView == LVS_REPORT && is_redrawing(infoPtr))
 		{
-		    /* this trick works for left aligned columns only */
+		    POINT ptOrigin;
+		    RECT rcCol = lpColumnInfo->rcHeader;
+		    
+		    LISTVIEW_GetOrigin(infoPtr, &ptOrigin);
+		    OffsetRect(&rcCol, ptOrigin.x, 0);
+		    
+		    rcCol.top = infoPtr->rcList.top;
+		    rcCol.bottom = infoPtr->rcList.bottom;
+
+		    /* resizing left-aligned columns leaves most of the left side untouched */
 		    if ((lpColumnInfo->fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT)
 		    {
-			rcCol.right = min (rcCol.right, lpColumnInfo->rcHeader.right);
-			rcCol.left = max (rcCol.left, rcCol.right - 3 * infoPtr->ntmAveCharWidth);
+			INT nMaxDirty = infoPtr->nEllipsisWidth + infoPtr->ntmMaxCharWidth + dx;
+			rcCol.left = max (rcCol.left, rcCol.right - nMaxDirty);
 		    }
-		    rcCol.top = infoPtr->rcList.top;
-		    rcCol.bottom = infoPtr->rcList.bottom;
+		    
 		    LISTVIEW_InvalidateRect(infoPtr, &rcCol);
 		}
 	    }


More information about the wine-patches mailing list