Listview updates (J4)

Dimitrie O. Paun dpaun at rogers.com
Wed Oct 2 16:06:30 CDT 2002


Relative to J3

ChangeLog
  -- Reorganize DrawItem
  -- Unify text attribute selection between Draw{Sub,}Item
  -- Usual cleanups, and simplifications.

--- dlls/comctl32/listview.c.J3	Wed Oct  2 13:22:36 2002
+++ dlls/comctl32/listview.c	Wed Oct  2 17:02:39 2002
@@ -2923,6 +2923,52 @@
     return nItem;
 }
 
+/* used by the drawing code */
+typedef struct tagTEXTATTR
+{
+    int      bkMode;
+    COLORREF bkColor;
+    COLORREF fgColor;
+} TEXTATTR;
+
+/* helper function for the drawing code */
+static inline void set_text_attr(HDC hdc, TEXTATTR *ta)
+{
+    ta->bkMode = SetBkMode(hdc, ta->bkMode);
+    ta->bkColor = SetBkColor(hdc, ta->bkColor);
+    ta->fgColor = SetTextColor(hdc, ta->fgColor);
+}
+
+/* helper function for the drawing code */
+static void select_text_attr(LISTVIEW_INFO *infoPtr, HDC hdc, BOOL isSelected, TEXTATTR *ta)
+{
+    ta->bkMode = OPAQUE;
+
+    if (isSelected && infoPtr->bFocus)
+    {
+	ta->bkColor = comctl32_color.clrHighlight;
+	ta->fgColor = comctl32_color.clrHighlightText;
+    }
+    else if (isSelected && (infoPtr->dwStyle & LVS_SHOWSELALWAYS))
+    {
+	ta->bkColor = comctl32_color.clr3dFace;
+	ta->fgColor = comctl32_color.clrBtnText;
+    }
+    else if ( (infoPtr->clrTextBk != CLR_DEFAULT) && (infoPtr->clrTextBk != CLR_NONE) )
+    {
+	ta->bkColor = infoPtr->clrTextBk;
+	ta->fgColor = infoPtr->clrText;
+    }
+    else
+    {
+	ta->bkMode  = TRANSPARENT;
+	ta->bkColor = GetBkColor(hdc);
+	ta->fgColor = infoPtr->clrText;
+    }
+
+    set_text_attr(hdc, ta);
+}
+
 /***
  * DESCRIPTION:
  * Erases the background of the given rectangle
@@ -3001,155 +3047,83 @@
  */
 static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, RECT rcItem)
 {
-  WCHAR szDispText[DISP_TEXT_SIZE];
-  INT nLabelWidth;
-  LVITEMW lvItem;
-  INT nMixMode;
-  DWORD dwBkColor;
-  DWORD dwTextColor,dwTextX;
-  BOOL bImage = FALSE;
-  INT   iBkMode = -1;
-  RECT* lprcFocus;
-  UINT  textoutOptions = ETO_OPAQUE | ETO_CLIPPED;
-
-  TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem);
+    WCHAR szDispText[DISP_TEXT_SIZE];
+    INT nLabelWidth, imagePadding = 0;
+    RECT* lprcFocus, rcOrig = rcItem;
+    LVITEMW lvItem;
+    TEXTATTR ta;
 
-  /* get information needed for drawing the item */
-  lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_INDENT;
-  lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK;
-  lvItem.iItem = nItem;
-  lvItem.iSubItem = 0;
-  lvItem.cchTextMax = DISP_TEXT_SIZE;
-  lvItem.pszText = szDispText;
-  *lvItem.pszText = '\0';
-  LISTVIEW_GetItemW(infoPtr, &lvItem, TRUE);
-  TRACE("   lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
+    TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem);
 
-  /* now check if we need to update the focus rectangle */
-  lprcFocus = infoPtr->bFocus && (lvItem.state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0;
-  
-  /* do indent */
-  if (lvItem.iIndent>0 && infoPtr->iconSize.cx > 0)
-  {
-    rcItem.left += infoPtr->iconSize.cx * lvItem.iIndent;
-  }
+    /* get information needed for drawing the item */
+    lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_INDENT;
+    lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK;
+    lvItem.iItem = nItem;
+    lvItem.iSubItem = 0;
+    lvItem.cchTextMax = DISP_TEXT_SIZE;
+    lvItem.pszText = szDispText;
+    *lvItem.pszText = '\0';
+    if (!LISTVIEW_GetItemW(infoPtr, &lvItem, TRUE)) return FALSE;
+    TRACE("   lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
 
-  /* state icons */
-  if (infoPtr->himlState != NULL)
-  {
-     UINT uStateImage = (lvItem.state & LVIS_STATEIMAGEMASK) >> 12;
-     if (uStateImage > 0)
-       ImageList_Draw(infoPtr->himlState, uStateImage - 1, hdc, rcItem.left,
-                      rcItem.top, ILD_NORMAL);
+    /* now check if we need to update the focus rectangle */
+    lprcFocus = infoPtr->bFocus && (lvItem.state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0;
+    if (lprcFocus) SetRectEmpty(lprcFocus);
 
-     rcItem.left += infoPtr->iconStateSize.cx;
-     bImage = TRUE;
-  }
+    /* do indent */  
+    rcItem.left += infoPtr->iconSize.cx * lvItem.iIndent;
 
-  /* small icons */
-  if (infoPtr->himlSmall != NULL)
-  {
-    if ((lvItem.state & LVIS_SELECTED) && (infoPtr->bFocus) &&
-        (lvItem.iImage>=0))
-    {
-      ImageList_SetBkColor(infoPtr->himlSmall, CLR_NONE);
-      ImageList_Draw(infoPtr->himlSmall, lvItem.iImage, hdc, rcItem.left,
-                     rcItem.top, ILD_SELECTED);
-    }
-    else if (lvItem.iImage>=0)
+    /* state icons */
+    if (infoPtr->himlState)
     {
-      ImageList_SetBkColor(infoPtr->himlSmall, CLR_NONE);
-      ImageList_Draw(infoPtr->himlSmall, lvItem.iImage, hdc, rcItem.left,
-                     rcItem.top, ILD_NORMAL);
+        UINT uStateImage = (lvItem.state & LVIS_STATEIMAGEMASK) >> 12;
+        if (uStateImage)
+	{
+	     ImageList_Draw(infoPtr->himlState, uStateImage - 1, hdc, 
+			    rcItem.left, rcItem.top, ILD_NORMAL);
+	}
+        rcItem.left += infoPtr->iconStateSize.cx;
+	imagePadding = IMAGE_PADDING;
     }
 
-    rcItem.left += infoPtr->iconSize.cx;
-    bImage = TRUE;
-  }
-
-  /* Don't bother painting item being edited */
-  if (infoPtr->bEditing && lprcFocus) 
-  {
-    SetRectEmpty(lprcFocus);
-    return FALSE;
-  }
-
-  if ((lvItem.state & LVIS_SELECTED) && (infoPtr->bFocus))
-  {
-    /* set item colors */
-    dwBkColor = SetBkColor(hdc, comctl32_color.clrHighlight);
-    dwTextColor = SetTextColor(hdc, comctl32_color.clrHighlightText);
-    /* set raster mode */
-    nMixMode = SetROP2(hdc, R2_XORPEN);
-  }
-  else if ((infoPtr->dwStyle & LVS_SHOWSELALWAYS) &&
-           (lvItem.state & LVIS_SELECTED) && (!infoPtr->bFocus))
-  {
-    dwBkColor = SetBkColor(hdc, comctl32_color.clr3dFace);
-    dwTextColor = SetTextColor(hdc, comctl32_color.clrBtnText);
-    /* set raster mode */
-    nMixMode = SetROP2(hdc, R2_COPYPEN);
-  }
-  else
-  {
-    /* set item colors */
-    if ( (infoPtr->clrTextBk == CLR_DEFAULT) || (infoPtr->clrTextBk == CLR_NONE) )
+    /* small icons */
+    if (infoPtr->himlSmall)
     {
-      dwBkColor = GetBkColor(hdc);
-      iBkMode = SetBkMode(hdc, TRANSPARENT);
-      textoutOptions &= ~ETO_OPAQUE;
-    }
-    else
-    {
-      dwBkColor = SetBkColor(hdc, infoPtr->clrTextBk);
-      iBkMode = SetBkMode(hdc, OPAQUE);
+	if (lvItem.iImage >= 0)
+	{
+	    UINT mode = (lvItem.state & LVIS_SELECTED) && (infoPtr->bFocus) ?
+		        ILD_SELECTED : ILD_NORMAL;
+	    ImageList_SetBkColor(infoPtr->himlSmall, CLR_NONE);
+	    ImageList_Draw(infoPtr->himlSmall, lvItem.iImage, hdc, 
+			   rcItem.left, rcItem.top, mode);
+	}
+        rcItem.left += infoPtr->iconSize.cx;
+	imagePadding = IMAGE_PADDING;
     }
 
-    dwTextColor = SetTextColor(hdc, infoPtr->clrText);
-    /* set raster mode */
-    nMixMode = SetROP2(hdc, R2_COPYPEN);
-  }
+    /* Don't bother painting item being edited */
+    if (infoPtr->bEditing && lprcFocus) 
+    	return FALSE;
 
-  nLabelWidth = LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
-  if (rcItem.left + nLabelWidth < rcItem.right)
-  {
-    rcItem.right = rcItem.left + nLabelWidth + TRAILING_PADDING;
-    if (bImage)
-      rcItem.right += IMAGE_PADDING;
-  }
+    select_text_attr(infoPtr, hdc, lvItem.state & LVIS_SELECTED, &ta);
 
-  /* draw label */
-  dwTextX = rcItem.left + 1;
-  if (bImage)
-    dwTextX += IMAGE_PADDING;
-
-  /* compute the focus rectangle */
-  if(lprcFocus) 
-  {
+    nLabelWidth = LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
+    rcItem.left += imagePadding;
+    rcItem.right = rcItem.left + nLabelWidth + TRAILING_PADDING;
+    if (rcItem.right > rcOrig.right) rcItem.right = rcOrig.right;
+    
     if (lvItem.pszText)
-      *lprcFocus = rcItem;
-    else 
-      SetRectEmpty(lprcFocus);
-  }
-  
-  if (lvItem.pszText)
-  {
-    TRACE("drawing text  rect=(%d,%d)-(%d,%d)\n",
-	  rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);
-    ExtTextOutW(hdc, dwTextX, rcItem.top, textoutOptions,
-                &rcItem, lvItem.pszText, lstrlenW(lvItem.pszText), NULL);
-  }
-
-  if (nMixMode != 0)
-  {
-    SetROP2(hdc, R2_COPYPEN);
-    SetBkColor(hdc, dwBkColor);
-    SetTextColor(hdc, dwTextColor);
-    if (iBkMode != -1)
-      SetBkMode(hdc, iBkMode);
-  }
+    {
+    	TRACE("drawing text=%s, in rect=%s\n", debugstr_w(lvItem.pszText), debugrect(&rcItem));
+	if(lprcFocus) *lprcFocus = rcItem;
+	if (lvItem.state & LVIS_SELECTED)
+	    ExtTextOutW(hdc, rcItem.left, rcItem.top, ETO_OPAQUE, &rcItem, 0, 0, 0);
+        DrawTextW(hdc, lvItem.pszText, -1, &rcItem, 
+	          DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_CENTER);
+    }
 
-  return lprcFocus != NULL;
+    set_text_attr(hdc, &ta);
+    return lprcFocus != NULL;
 }
 
 /***
@@ -3352,8 +3326,7 @@
     DWORD cditemmode = CDRF_DODEFAULT;
     LONG lStyle = infoPtr->dwStyle;
     UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
-    COLORREF oldBkClr, oldFgClr;
-    INT oldBkMode;
+    TEXTATTR tmpTa, oldTa;
     COLUMNCACHE *lpCols;
     LVCOLUMNW lvColumn;
     LVITEMW lvItem;
@@ -3422,9 +3395,9 @@
     nDrawPosY = infoPtr->rcList.top + (nItem - nTop) * infoPtr->nItemHeight;
 
     /* save dc values we're gonna trash while drawing */
-    oldBkMode = GetBkMode(hdc);
-    oldBkClr = GetBkColor(hdc);
-    oldFgClr = GetTextColor(hdc);
+    oldTa.bkMode = GetBkMode(hdc);
+    oldTa.bkColor = GetBkColor(hdc);
+    oldTa.fgColor = GetTextColor(hdc);
    
     /* iterate through the invalidated rows */ 
     for (; nItem < nLast; nItem++, nDrawPosY += infoPtr->nItemHeight)
@@ -3482,27 +3455,9 @@
 	}
 
 	/* draw the background of the selection rectangle, if need be */
-	SetBkMode(hdc, OPAQUE);
+	select_text_attr(infoPtr, hdc, bFullSelected && (lvItem.state & LVIS_SELECTED), &tmpTa);
 	if (bFullSelected && (lvItem.state & LVIS_SELECTED))
-	{
-	    if (infoPtr->bFocus)
-	    {
-		SetBkColor(hdc, comctl32_color.clrHighlight);
-   		SetTextColor(hdc, comctl32_color.clrHighlightText);
-	    }
-	    else
-	    {
-		SetBkColor(hdc, comctl32_color.clr3dFace);
-		SetTextColor(hdc, comctl32_color.clrBtnText);
-	    }
-	    ExtTextOutW(hdc, rcFullSelect.left, rcFullSelect.top, ETO_CLIPPED | ETO_OPAQUE, &rcFullSelect, 0, 0, 0);
-	}
-	else
-	{
-	    if ( (infoPtr->clrTextBk == CLR_DEFAULT) || (infoPtr->clrTextBk == CLR_NONE) )
-		SetBkMode(hdc, TRANSPARENT);
-	    SetTextColor(hdc, infoPtr->clrText);
-	}
+	    ExtTextOutW(hdc, rcFullSelect.left, rcFullSelect.top, ETO_OPAQUE, &rcFullSelect, 0, 0, 0);
 	    
 	/* iterate through the invalidated columns */
     	isFocused = FALSE;	    
@@ -3535,9 +3490,7 @@
     }
 
     /* cleanup the mess */
-    SetTextColor(hdc, oldFgClr);
-    SetBkColor(hdc, oldBkClr);
-    SetBkMode(hdc, oldBkMode);
+    set_text_attr(hdc, &oldTa);
     COMCTL32_Free(lpCols);
 }
 




More information about the wine-patches mailing list