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; }