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