Commit ffd4bd37 authored by Dimitrie O. Paun's avatar Dimitrie O. Paun Committed by Alexandre Julliard

Handle custom draw notifications properly.

Various cleanups, and simplifications.
parent d2d4baf9
...@@ -661,19 +661,42 @@ static BOOL notify_dispinfoT(LISTVIEW_INFO *infoPtr, INT notificationCode, LPNML ...@@ -661,19 +661,42 @@ static BOOL notify_dispinfoT(LISTVIEW_INFO *infoPtr, INT notificationCode, LPNML
static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc, LPRECT rcBounds, LVITEMW *lpLVItem) static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc, LPRECT rcBounds, LVITEMW *lpLVItem)
{ {
BOOL isSelected;
ZeroMemory(lpnmlvcd, sizeof(NMLVCUSTOMDRAW)); ZeroMemory(lpnmlvcd, sizeof(NMLVCUSTOMDRAW));
lpnmlvcd->nmcd.hdc = hdc; lpnmlvcd->nmcd.hdc = hdc;
lpnmlvcd->nmcd.rc = *rcBounds; lpnmlvcd->nmcd.rc = *rcBounds;
if (lpLVItem) 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_SELECTED) lpnmlvcd->nmcd.uItemState |= CDIS_SELECTED;
if (lpLVItem->state & LVIS_FOCUSED) lpnmlvcd->nmcd.uItemState |= CDIS_FOCUS; if (lpLVItem->state & LVIS_FOCUSED) lpnmlvcd->nmcd.uItemState |= CDIS_FOCUS;
if (lpLVItem->iItem == infoPtr->nHotItem) lpnmlvcd->nmcd.uItemState |= CDIS_HOT; if (lpLVItem->iItem == infoPtr->nHotItem) lpnmlvcd->nmcd.uItemState |= CDIS_HOT;
lpnmlvcd->nmcd.lItemlParam = lpLVItem->lParam; 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) static inline DWORD notify_customdraw (LISTVIEW_INFO *infoPtr, DWORD dwDrawStage, NMLVCUSTOMDRAW *lpnmlvcd)
...@@ -2937,50 +2960,18 @@ static INT LISTVIEW_GetTopIndex(LISTVIEW_INFO *infoPtr) ...@@ -2937,50 +2960,18 @@ static INT LISTVIEW_GetTopIndex(LISTVIEW_INFO *infoPtr)
return nItem; 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 */ /* 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 ( (lpnmlvcd->clrTextBk != CLR_DEFAULT) && (lpnmlvcd->clrTextBk != CLR_NONE) )
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; SetBkMode(hdc, OPAQUE);
ta->fgColor = comctl32_color.clrBtnText; SetBkColor(hdc, lpnmlvcd->clrTextBk);
}
else if ( (infoPtr->clrTextBk != CLR_DEFAULT) && (infoPtr->clrTextBk != CLR_NONE) )
{
ta->bkColor = infoPtr->clrTextBk;
ta->fgColor = infoPtr->clrText;
} }
else else
{ SetBkMode(hdc, TRANSPARENT);
ta->bkMode = TRANSPARENT;
ta->bkColor = GetBkColor(hdc);
ta->fgColor = infoPtr->clrText;
}
set_text_attr(hdc, ta); SetTextColor(hdc, lpnmlvcd->clrText);
} }
/*** /***
...@@ -3046,10 +3037,9 @@ static BOOL LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ...@@ -3046,10 +3037,9 @@ static BOOL LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem,
cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd); cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd);
if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint; 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"); 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); DrawTextW(hdc, lvItem.pszText, -1, &rcItem, LV_SL_DT_FLAGS | align);
postpaint: postpaint:
...@@ -3080,10 +3070,9 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, RECT r ...@@ -3080,10 +3070,9 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, RECT r
WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' }; WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
DWORD cditemmode = CDRF_DODEFAULT; DWORD cditemmode = CDRF_DODEFAULT;
INT nLabelWidth, imagePadding = 0; INT nLabelWidth, imagePadding = 0;
RECT* lprcFocus, rcOrig = rcItem; RECT* lprcFocus, rcSelect;
NMLVCUSTOMDRAW nmlvcd; NMLVCUSTOMDRAW nmlvcd;
LVITEMW lvItem; LVITEMW lvItem;
TEXTATTR ta;
TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem); TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem);
...@@ -3140,22 +3129,25 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, RECT r ...@@ -3140,22 +3129,25 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, RECT r
/* Don't bother painting item being edited */ /* Don't bother painting item being edited */
if (infoPtr->bEditing && lprcFocus) goto postpaint; 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); nLabelWidth = LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
rcItem.left += imagePadding; rcItem.left += imagePadding;
rcItem.right = rcItem.left + nLabelWidth + TRAILING_PADDING; rcSelect = rcItem;
if (rcItem.right > rcOrig.right) rcItem.right = rcOrig.right; 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) if (lvItem.pszText)
{ {
TRACE("drawing text=%s, in rect=%s\n", debugstr_w(lvItem.pszText), debugrect(&rcItem)); TRACE("drawing text=%s, in rect=%s\n", debugstr_w(lvItem.pszText), debugrect(&rcItem));
if(lprcFocus) *lprcFocus = 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); DrawTextW(hdc, lvItem.pszText, -1, &rcItem, LV_SL_DT_FLAGS | DT_CENTER);
} }
set_text_attr(hdc, &ta);
postpaint: postpaint:
if (cditemmode & CDRF_NOTIFYPOSTPAINT) if (cditemmode & CDRF_NOTIFYPOSTPAINT)
...@@ -3185,7 +3177,6 @@ static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, D ...@@ -3185,7 +3177,6 @@ static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, D
NMLVCUSTOMDRAW nmlvcd; NMLVCUSTOMDRAW nmlvcd;
LVITEMW lvItem; LVITEMW lvItem;
UINT uFormat; UINT uFormat;
TEXTATTR ta;
TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem); TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem);
...@@ -3209,10 +3200,6 @@ static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, D ...@@ -3209,10 +3200,6 @@ static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, D
cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd); cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd);
if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint; 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 */ /* Set the item to the boundary box for now */
TRACE("rcIcon=%s, rcLabel=%s\n", debugrect(&rcIcon), debugrect(&rcLabel)); TRACE("rcIcon=%s, rcLabel=%s\n", debugrect(&rcIcon), debugrect(&rcLabel));
...@@ -3241,7 +3228,7 @@ static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, D ...@@ -3241,7 +3228,7 @@ static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, D
goto postpaint; 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; uFormat = lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS;
...@@ -3263,8 +3250,6 @@ static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, D ...@@ -3263,8 +3250,6 @@ static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, D
if(lprcFocus) *lprcFocus = rcLabel; if(lprcFocus) *lprcFocus = rcLabel;
set_text_attr(hdc, &ta);
postpaint: postpaint:
if (cditemmode & CDRF_NOTIFYPOSTPAINT) if (cditemmode & CDRF_NOTIFYPOSTPAINT)
notify_customdraw(infoPtr, CDDS_ITEMPOSTPAINT, &nmlvcd); notify_customdraw(infoPtr, CDDS_ITEMPOSTPAINT, &nmlvcd);
...@@ -3362,7 +3347,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode ...@@ -3362,7 +3347,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode
INT nColumnCount, nFirstCol, nLastCol; INT nColumnCount, nFirstCol, nLastCol;
RECT rcItem, rcClip, rcFullSelect; RECT rcItem, rcClip, rcFullSelect;
BOOL bFullSelected, isFocused; BOOL bFullSelected, isFocused;
TEXTATTR tmpTa, oldTa;
COLUMNCACHE *lpCols; COLUMNCACHE *lpCols;
LVCOLUMNW lvColumn; LVCOLUMNW lvColumn;
LVITEMW item; LVITEMW item;
...@@ -3408,11 +3392,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode ...@@ -3408,11 +3392,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode
lpCols[j].align = DT_CENTER; 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 */ /* figure out what we need to draw */
iterator_clippeditems(&i, infoPtr, hdc); iterator_clippeditems(&i, infoPtr, hdc);
...@@ -3445,11 +3424,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode ...@@ -3445,11 +3424,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode
OffsetRect(&rcFullSelect, ptOrig.x, ptOrig.y); 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 */ /* iterate through the invalidated columns */
for (j = nFirstCol; j <= nLastCol; j++) for (j = nFirstCol; j <= nLastCol; j++)
{ {
...@@ -3476,7 +3450,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode ...@@ -3476,7 +3450,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode
iterator_destroy(&i); iterator_destroy(&i);
/* cleanup the mess */ /* cleanup the mess */
set_text_attr(hdc, &oldTa);
COMCTL32_Free(lpCols); COMCTL32_Free(lpCols);
} }
...@@ -3572,20 +3545,24 @@ static void LISTVIEW_RefreshIcon(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode) ...@@ -3572,20 +3545,24 @@ static void LISTVIEW_RefreshIcon(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode)
static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc) static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc)
{ {
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
COLORREF oldBkColor, oldTextColor;
NMLVCUSTOMDRAW nmlvcd; NMLVCUSTOMDRAW nmlvcd;
HFONT hOldFont; HFONT hOldFont;
DWORD cdmode; DWORD cdmode;
INT oldBkMode;
RECT rcClient; RECT rcClient;
LISTVIEW_DUMP(infoPtr); LISTVIEW_DUMP(infoPtr);
infoPtr->bIsDrawing = TRUE; infoPtr->bIsDrawing = TRUE;
GetClientRect(infoPtr->hwndSelf, &rcClient); /* save dc values we're gonna trash while drawing */
/* select font */
hOldFont = SelectObject(hdc, infoPtr->hFont); 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); customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient, NULL);
cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd); cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd);
if (cdmode & CDRF_SKIPDEFAULT) goto enddraw; if (cdmode & CDRF_SKIPDEFAULT) goto enddraw;
...@@ -3612,7 +3589,9 @@ enddraw: ...@@ -3612,7 +3589,9 @@ enddraw:
/* unselect objects */ /* unselect objects */
SelectObject(hdc, hOldFont); SelectObject(hdc, hOldFont);
SetBkMode(hdc, oldBkMode);
SetBkColor(hdc, oldBkColor);
SetTextColor(hdc, oldTextColor);
infoPtr->bIsDrawing = FALSE; infoPtr->bIsDrawing = FALSE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment