Listview N7

Dimitrie O. Paun dpaun at rogers.com
Thu Oct 10 15:40:16 CDT 2002


On October 10, 2002 04:36 pm, Greg Turner wrote:
> On Thursday 10 October 2002 03:19 pm, Dimitrie O. Paun wrote:
> > This one breaks full row select in REPORT mode,
> > will get fixed by a later patch (requires some
> > infrastructure changes which are not in place yet).
> >
> > ChangeLog
> >   Handle custom draw notifications properly
> >   Various cleanups, and simplifications.
>
> I think you forgot to enclose the diff with this one....

Good point.

--- dlls/comctl32/listview.c.N6	Thu Oct 10 14:41:45 2002
+++ dlls/comctl32/listview.c	Thu Oct 10 16:12:57 2002
@@ -661,19 +661,42 @@
 
 static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc, LPRECT rcBounds, LVITEMW *lpLVItem)
 {
+    BOOL isSelected;
+    
     ZeroMemory(lpnmlvcd, sizeof(NMLVCUSTOMDRAW));
-    lpnmlvcd->nmcd.hdc         = hdc;
-    lpnmlvcd->nmcd.rc          = *rcBounds;
+    lpnmlvcd->nmcd.hdc = hdc;
+    lpnmlvcd->nmcd.rc = *rcBounds;
     if (lpLVItem)
     {
-	lpnmlvcd->nmcd.dwItemSpec  = lpLVItem->iItem;
+	lpnmlvcd->nmcd.dwItemSpec = lpLVItem->iItem;
+	lpnmlvcd->iSubItem = lpLVItem->iSubItem;
         if (lpLVItem->state & LVIS_SELECTED) lpnmlvcd->nmcd.uItemState |= CDIS_SELECTED;
 	if (lpLVItem->state & LVIS_FOCUSED) lpnmlvcd->nmcd.uItemState |= CDIS_FOCUS;
 	if (lpLVItem->iItem == infoPtr->nHotItem) lpnmlvcd->nmcd.uItemState |= CDIS_HOT;
 	lpnmlvcd->nmcd.lItemlParam = lpLVItem->lParam;
     }
-    lpnmlvcd->clrText          = infoPtr->clrText;
-    lpnmlvcd->clrTextBk        = infoPtr->clrBk;
+
+    isSelected = lpnmlvcd->nmcd.uItemState & CDIS_SELECTED;
+    /* subitems are selected only in full-row-select, report mode */
+    if ( lpnmlvcd->iSubItem != 0 && 
+	 !((infoPtr->dwStyle & LVS_TYPEMASK) == LVS_REPORT && 
+	   (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) )
+	isSelected = FALSE;
+    if (isSelected && infoPtr->bFocus)
+    {
+	lpnmlvcd->clrTextBk = comctl32_color.clrHighlight;
+	lpnmlvcd->clrText   = comctl32_color.clrHighlightText;
+    }
+    else if (isSelected && (infoPtr->dwStyle & LVS_SHOWSELALWAYS))
+    {
+	lpnmlvcd->clrTextBk = comctl32_color.clr3dFace;
+	lpnmlvcd->clrText   = comctl32_color.clrBtnText;
+    }
+    else
+    {
+	lpnmlvcd->clrTextBk = infoPtr->clrTextBk;
+	lpnmlvcd->clrText   = infoPtr->clrText;
+    }
 }
 
 static inline DWORD notify_customdraw (LISTVIEW_INFO *infoPtr, DWORD dwDrawStage, NMLVCUSTOMDRAW *lpnmlvcd)
@@ -2938,50 +2961,18 @@
     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)
+static void select_text_attr(LISTVIEW_INFO *infoPtr, HDC hdc, NMLVCUSTOMDRAW *lpnmlvcd)
 {
-    ta->bkMode = OPAQUE;
-
-    if (isSelected && infoPtr->bFocus)
-    {
-	ta->bkColor = comctl32_color.clrHighlight;
-	ta->fgColor = comctl32_color.clrHighlightText;
-    }
-    else if (isSelected && (infoPtr->dwStyle & LVS_SHOWSELALWAYS))
+    if ( (lpnmlvcd->clrTextBk != CLR_DEFAULT) && (lpnmlvcd->clrTextBk != CLR_NONE) )
     {
-	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;
+	SetBkMode(hdc, OPAQUE);
+	SetBkColor(hdc, lpnmlvcd->clrTextBk);
     }
     else
-    {
-	ta->bkMode  = TRANSPARENT;
-	ta->bkColor = GetBkColor(hdc);
-	ta->fgColor = infoPtr->clrText;
-    }
+	SetBkMode(hdc, TRANSPARENT);
 
-    set_text_attr(hdc, ta);
+    SetTextColor(hdc, lpnmlvcd->clrText);
 }
 
 /***
@@ -3047,10 +3038,9 @@
         cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd);
     if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint;
 
-    /* FIXME: set the text attr in here, they may change! */
-
     if (lvItem.iImage) FIXME("Draw the image for the subitem\n");
-    
+
+    select_text_attr(infoPtr, hdc, &nmlvcd);
     DrawTextW(hdc, lvItem.pszText, -1, &rcItem, LV_SL_DT_FLAGS | align);
 
 postpaint:
@@ -3081,10 +3071,9 @@
     WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
     DWORD cditemmode = CDRF_DODEFAULT;
     INT nLabelWidth, imagePadding = 0;
-    RECT* lprcFocus, rcOrig = rcItem;
+    RECT* lprcFocus, rcSelect;
     NMLVCUSTOMDRAW nmlvcd;
     LVITEMW lvItem;
-    TEXTATTR ta;
 
     TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem);
 
@@ -3141,22 +3130,25 @@
     /* Don't bother painting item being edited */
     if (infoPtr->bEditing && lprcFocus) goto postpaint;
 
-    select_text_attr(infoPtr, hdc, lvItem.state & LVIS_SELECTED, &ta);
+    select_text_attr(infoPtr, hdc, &nmlvcd);
 
     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;
+    rcSelect = rcItem;    
+    rcItem.right = min(rcItem.left + nLabelWidth + TRAILING_PADDING, rcItem.right);
+    if (!(infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) 
+    {
+	rcSelect.right = rcItem.right;
+	if (!lvItem.pszText) rcSelect.left = rcSelect.right;
+    }
     
+    ExtTextOutW(hdc, rcSelect.left, rcSelect.top, ETO_OPAQUE, &rcSelect, 0, 0, 0);
     if (lvItem.pszText)
     {
     	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, LV_SL_DT_FLAGS | DT_CENTER);
     }
-    set_text_attr(hdc, &ta);
 
 postpaint:
     if (cditemmode & CDRF_NOTIFYPOSTPAINT)
@@ -3186,7 +3178,6 @@
     NMLVCUSTOMDRAW nmlvcd;
     LVITEMW lvItem;
     UINT uFormat;
-    TEXTATTR ta;
 
     TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem);
 
@@ -3210,10 +3201,6 @@
         cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd);
     if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint;
 
-    /* FIXME: pass the mnlvcd to select text attr */
-    infoPtr->clrText = nmlvcd.clrText;
-    infoPtr->clrBk   = nmlvcd.clrTextBk;
-    
     /* Set the item to the boundary box for now */
     TRACE("rcIcon=%s, rcLabel=%s\n", debugrect(&rcIcon), debugrect(&rcLabel));
 
@@ -3242,7 +3229,7 @@
         goto postpaint;
     }
 
-    select_text_attr(infoPtr, hdc, lvItem.state & LVIS_SELECTED, &ta);
+    select_text_attr(infoPtr, hdc, &nmlvcd);
 
     uFormat = lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS;
 
@@ -3264,8 +3251,6 @@
 
     if(lprcFocus) *lprcFocus = rcLabel;
 
-    set_text_attr(hdc, &ta);
-
 postpaint:    
     if (cditemmode & CDRF_NOTIFYPOSTPAINT)
         notify_customdraw(infoPtr, CDDS_ITEMPOSTPAINT, &nmlvcd);
@@ -3363,7 +3348,6 @@
     INT nColumnCount, nFirstCol, nLastCol;
     RECT rcItem, rcClip, rcFullSelect;
     BOOL bFullSelected, isFocused;
-    TEXTATTR tmpTa, oldTa;
     COLUMNCACHE *lpCols;
     LVCOLUMNW lvColumn;
     LVITEMW item;
@@ -3409,11 +3393,6 @@
 	    lpCols[j].align = DT_CENTER;
     }
 
-    /* save dc values we're gonna trash while drawing */
-    oldTa.bkMode = GetBkMode(hdc);
-    oldTa.bkColor = GetBkColor(hdc);
-    oldTa.fgColor = GetTextColor(hdc);
-   
     /* figure out what we need to draw */
     iterator_clippeditems(&i, infoPtr, hdc);
     
@@ -3446,11 +3425,6 @@
 	    OffsetRect(&rcFullSelect, ptOrig.x, ptOrig.y);
 	}
 
-	/* draw the background of the selection rectangle, if need be */
-	select_text_attr(infoPtr, hdc, bFullSelected && (item.state & LVIS_SELECTED), &tmpTa);
-	if (bFullSelected && (item.state & LVIS_SELECTED))
-	    ExtTextOutW(hdc, rcFullSelect.left, rcFullSelect.top, ETO_OPAQUE, &rcFullSelect, 0, 0, 0);
-	    
 	/* iterate through the invalidated columns */
 	for (j = nFirstCol; j <= nLastCol; j++)
 	{
@@ -3477,7 +3451,6 @@
     iterator_destroy(&i);
 
     /* cleanup the mess */
-    set_text_attr(hdc, &oldTa);
     COMCTL32_Free(lpCols);
 }
 
@@ -3573,20 +3546,24 @@
 static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc)
 {
     UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
+    COLORREF oldBkColor, oldTextColor;
     NMLVCUSTOMDRAW nmlvcd;
     HFONT hOldFont;
     DWORD cdmode;
+    INT oldBkMode;
     RECT rcClient;
 
     LISTVIEW_DUMP(infoPtr);
   
     infoPtr->bIsDrawing = TRUE;
 
-    GetClientRect(infoPtr->hwndSelf, &rcClient);
- 
-    /* select font */
+    /* save dc values we're gonna trash while drawing */
     hOldFont = SelectObject(hdc, infoPtr->hFont);
-
+    oldBkMode = GetBkMode(hdc);
+    oldBkColor = GetBkColor(hdc);
+    oldTextColor = GetTextColor(hdc);
+   
+    GetClientRect(infoPtr->hwndSelf, &rcClient);
     customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient, NULL);
     cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd);
     if (cdmode & CDRF_SKIPDEFAULT) goto enddraw;
@@ -3613,7 +3590,9 @@
 
     /* unselect objects */
     SelectObject(hdc, hOldFont);
-
+    SetBkMode(hdc, oldBkMode);
+    SetBkColor(hdc, oldBkColor);
+    SetTextColor(hdc, oldTextColor);
     infoPtr->bIsDrawing = FALSE;
 }
 




More information about the wine-patches mailing list