Generate custom draw notifications for ownerdraw listviews (based on a
patch by Maxime Bellengé). Reorganize the custom draw code for better reuse.
This commit is contained in:
parent
7b55bc45eb
commit
dfdeaaf922
|
@ -849,21 +849,73 @@ static BOOL notify_dispinfoT(LISTVIEW_INFO *infoPtr, INT notificationCode, LPNML
|
||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc, const RECT *rcBounds)
|
static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc,
|
||||||
|
const RECT *rcBounds, const LVITEMW *lplvItem)
|
||||||
{
|
{
|
||||||
ZeroMemory(lpnmlvcd, sizeof(NMLVCUSTOMDRAW));
|
ZeroMemory(lpnmlvcd, sizeof(NMLVCUSTOMDRAW));
|
||||||
lpnmlvcd->nmcd.hdc = hdc;
|
lpnmlvcd->nmcd.hdc = hdc;
|
||||||
lpnmlvcd->nmcd.rc = *rcBounds;
|
lpnmlvcd->nmcd.rc = *rcBounds;
|
||||||
lpnmlvcd->clrTextBk = infoPtr->clrTextBk;
|
lpnmlvcd->clrTextBk = infoPtr->clrTextBk;
|
||||||
lpnmlvcd->clrText = infoPtr->clrText;
|
lpnmlvcd->clrText = infoPtr->clrText;
|
||||||
|
if (!lplvItem) return;
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline DWORD notify_customdraw (LISTVIEW_INFO *infoPtr, DWORD dwDrawStage, NMLVCUSTOMDRAW *lpnmlvcd)
|
static inline DWORD notify_customdraw (LISTVIEW_INFO *infoPtr, DWORD dwDrawStage, NMLVCUSTOMDRAW *lpnmlvcd)
|
||||||
{
|
{
|
||||||
lpnmlvcd->nmcd.dwDrawStage = dwDrawStage;
|
lpnmlvcd->nmcd.dwDrawStage = dwDrawStage;
|
||||||
|
if (lpnmlvcd->nmcd.dwItemSpec) lpnmlvcd->nmcd.dwDrawStage |= CDDS_ITEM;
|
||||||
return notify_hdr(infoPtr, NM_CUSTOMDRAW, &lpnmlvcd->nmcd.hdr);
|
return notify_hdr(infoPtr, NM_CUSTOMDRAW, &lpnmlvcd->nmcd.hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD notify_prepaint (LISTVIEW_INFO *infoPtr, HDC hdc, NMLVCUSTOMDRAW *lpnmlvcd)
|
||||||
|
{
|
||||||
|
BOOL isSelected = lpnmlvcd->nmcd.uItemState & CDIS_SELECTED;
|
||||||
|
DWORD cditemmode = notify_customdraw(infoPtr, CDDS_PREPAINT, lpnmlvcd);
|
||||||
|
|
||||||
|
if (cditemmode & CDRF_SKIPDEFAULT) return cditemmode;
|
||||||
|
|
||||||
|
/* apprently, for selected items, we have to override the returned values */
|
||||||
|
if (isSelected)
|
||||||
|
{
|
||||||
|
if (infoPtr->bFocus)
|
||||||
|
{
|
||||||
|
lpnmlvcd->clrTextBk = comctl32_color.clrHighlight;
|
||||||
|
lpnmlvcd->clrText = comctl32_color.clrHighlightText;
|
||||||
|
}
|
||||||
|
else if (infoPtr->dwStyle & LVS_SHOWSELALWAYS)
|
||||||
|
{
|
||||||
|
lpnmlvcd->clrTextBk = comctl32_color.clr3dFace;
|
||||||
|
lpnmlvcd->clrText = comctl32_color.clrBtnText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the text attributes */
|
||||||
|
if (lpnmlvcd->clrTextBk != CLR_NONE)
|
||||||
|
{
|
||||||
|
SetBkMode(hdc, OPAQUE);
|
||||||
|
if (lpnmlvcd->clrTextBk == CLR_DEFAULT)
|
||||||
|
SetBkColor(hdc, infoPtr->clrTextBkDefault);
|
||||||
|
else
|
||||||
|
SetBkColor(hdc,lpnmlvcd->clrTextBk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetBkMode(hdc, TRANSPARENT);
|
||||||
|
SetTextColor(hdc, lpnmlvcd->clrText);
|
||||||
|
|
||||||
|
return cditemmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline DWORD notify_postpaint (LISTVIEW_INFO *infoPtr, NMLVCUSTOMDRAW *lpnmlvcd)
|
||||||
|
{
|
||||||
|
return notify_customdraw(infoPtr, CDDS_POSTPAINT, lpnmlvcd);
|
||||||
|
}
|
||||||
|
|
||||||
/******** Item iterator functions **********************************/
|
/******** Item iterator functions **********************************/
|
||||||
|
|
||||||
static RANGES ranges_create(int count);
|
static RANGES ranges_create(int count);
|
||||||
|
@ -3504,33 +3556,12 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS
|
||||||
debugrect(&rcBox), debugrect(&rcState), debugrect(&rcIcon), debugrect(&rcLabel));
|
debugrect(&rcBox), debugrect(&rcState), debugrect(&rcIcon), debugrect(&rcLabel));
|
||||||
|
|
||||||
/* fill in the custom draw structure */
|
/* fill in the custom draw structure */
|
||||||
customdraw_fill(&nmlvcd, infoPtr, hdc, &rcBox);
|
customdraw_fill(&nmlvcd, infoPtr, hdc, &rcBox, &lvItem);
|
||||||
nmlvcd.nmcd.dwItemSpec = lvItem.iItem;
|
|
||||||
nmlvcd.iSubItem = lvItem.iSubItem;
|
|
||||||
if (lvItem.state & LVIS_SELECTED) nmlvcd.nmcd.uItemState |= CDIS_SELECTED;
|
|
||||||
if (lvItem.state & LVIS_FOCUSED) nmlvcd.nmcd.uItemState |= CDIS_FOCUS;
|
|
||||||
if (lvItem.iItem == infoPtr->nHotItem) nmlvcd.nmcd.uItemState |= CDIS_HOT;
|
|
||||||
nmlvcd.nmcd.lItemlParam = lvItem.lParam;
|
|
||||||
|
|
||||||
if (cdmode & CDRF_NOTIFYITEMDRAW)
|
if (cdmode & CDRF_NOTIFYITEMDRAW)
|
||||||
cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd);
|
cditemmode = notify_prepaint (infoPtr, hdc, &nmlvcd);
|
||||||
if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint;
|
if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint;
|
||||||
|
|
||||||
/* apprently, for selected items, we have to override the returned values */
|
|
||||||
if (lvItem.state & LVIS_SELECTED)
|
|
||||||
{
|
|
||||||
if (infoPtr->bFocus)
|
|
||||||
{
|
|
||||||
nmlvcd.clrTextBk = comctl32_color.clrHighlight;
|
|
||||||
nmlvcd.clrText = comctl32_color.clrHighlightText;
|
|
||||||
}
|
|
||||||
else if (infoPtr->dwStyle & LVS_SHOWSELALWAYS)
|
|
||||||
{
|
|
||||||
nmlvcd.clrTextBk = comctl32_color.clr3dFace;
|
|
||||||
nmlvcd.clrText = comctl32_color.clrBtnText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* in full row select, subitems, will just use main item's colors */
|
/* in full row select, subitems, will just use main item's colors */
|
||||||
if (nSubItem && uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
|
if (nSubItem && uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
|
||||||
nmlvcd.clrTextBk = CLR_NONE;
|
nmlvcd.clrTextBk = CLR_NONE;
|
||||||
|
@ -3558,16 +3589,6 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS
|
||||||
/* Don't bother painting item being edited */
|
/* Don't bother painting item being edited */
|
||||||
if (infoPtr->hwndEdit && nItem == infoPtr->nEditLabelItem && nSubItem == 0) goto postpaint;
|
if (infoPtr->hwndEdit && nItem == infoPtr->nEditLabelItem && nSubItem == 0) goto postpaint;
|
||||||
|
|
||||||
/* Set the text attributes */
|
|
||||||
if (nmlvcd.clrTextBk != CLR_NONE)
|
|
||||||
{
|
|
||||||
SetBkMode(hdc, OPAQUE);
|
|
||||||
SetBkColor(hdc, nmlvcd.clrTextBk == CLR_DEFAULT ? infoPtr->clrTextBkDefault : nmlvcd.clrTextBk);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SetBkMode(hdc, TRANSPARENT);
|
|
||||||
SetTextColor(hdc, nmlvcd.clrText);
|
|
||||||
|
|
||||||
/* draw the selection background, if we're drawing the main item */
|
/* draw the selection background, if we're drawing the main item */
|
||||||
if (nSubItem == 0)
|
if (nSubItem == 0)
|
||||||
{
|
{
|
||||||
|
@ -3603,7 +3624,7 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS
|
||||||
|
|
||||||
postpaint:
|
postpaint:
|
||||||
if (cditemmode & CDRF_NOTIFYPOSTPAINT)
|
if (cditemmode & CDRF_NOTIFYPOSTPAINT)
|
||||||
notify_customdraw(infoPtr, CDDS_ITEMPOSTPAINT, &nmlvcd);
|
notify_postpaint(infoPtr, &nmlvcd);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3618,10 +3639,12 @@ postpaint:
|
||||||
* RETURN:
|
* RETURN:
|
||||||
* None
|
* None
|
||||||
*/
|
*/
|
||||||
static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc)
|
static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc, DWORD cdmode)
|
||||||
{
|
{
|
||||||
UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
|
UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
|
||||||
HWND hwndParent = GetParent(infoPtr->hwndSelf);
|
HWND hwndParent = GetParent(infoPtr->hwndSelf);
|
||||||
|
DWORD cditemmode = CDRF_DODEFAULT;
|
||||||
|
NMLVCUSTOMDRAW nmlvcd;
|
||||||
POINT Origin, Position;
|
POINT Origin, Position;
|
||||||
DRAWITEMSTRUCT dis;
|
DRAWITEMSTRUCT dis;
|
||||||
LVITEMW item;
|
LVITEMW item;
|
||||||
|
@ -3659,7 +3682,18 @@ static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC h
|
||||||
dis.itemData = item.lParam;
|
dis.itemData = item.lParam;
|
||||||
|
|
||||||
TRACE("item=%s, rcItem=%s\n", debuglvitem_t(&item, TRUE), debugrect(&dis.rcItem));
|
TRACE("item=%s, rcItem=%s\n", debuglvitem_t(&item, TRUE), debugrect(&dis.rcItem));
|
||||||
SendMessageW(hwndParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
|
|
||||||
|
if (cdmode & CDRF_NOTIFYITEMDRAW)
|
||||||
|
{
|
||||||
|
customdraw_fill(&nmlvcd, infoPtr, hdc, &dis.rcItem, &item);
|
||||||
|
cditemmode = notify_prepaint (infoPtr, hdc, &nmlvcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cditemmode & CDRF_SKIPDEFAULT))
|
||||||
|
SendMessageW(hwndParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
|
||||||
|
|
||||||
|
if (cditemmode & CDRF_NOTIFYPOSTPAINT)
|
||||||
|
notify_postpaint(infoPtr, &nmlvcd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3800,8 +3834,8 @@ static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc)
|
||||||
oldClrText = infoPtr->clrText;
|
oldClrText = infoPtr->clrText;
|
||||||
|
|
||||||
GetClientRect(infoPtr->hwndSelf, &rcClient);
|
GetClientRect(infoPtr->hwndSelf, &rcClient);
|
||||||
customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient);
|
customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient, 0);
|
||||||
cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd);
|
cdmode = notify_prepaint(infoPtr, hdc, &nmlvcd);
|
||||||
if (cdmode & CDRF_SKIPDEFAULT) goto enddraw;
|
if (cdmode & CDRF_SKIPDEFAULT) goto enddraw;
|
||||||
|
|
||||||
/* Use these colors to draw the items */
|
/* Use these colors to draw the items */
|
||||||
|
@ -3827,7 +3861,7 @@ static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && (uView == LVS_REPORT))
|
if ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && (uView == LVS_REPORT))
|
||||||
LISTVIEW_RefreshOwnerDraw(infoPtr, &i, hdc);
|
LISTVIEW_RefreshOwnerDraw(infoPtr, &i, hdc, cdmode);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (uView == LVS_REPORT)
|
if (uView == LVS_REPORT)
|
||||||
|
@ -3843,7 +3877,7 @@ static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc)
|
||||||
|
|
||||||
enddraw:
|
enddraw:
|
||||||
if (cdmode & CDRF_NOTIFYPOSTPAINT)
|
if (cdmode & CDRF_NOTIFYPOSTPAINT)
|
||||||
notify_customdraw(infoPtr, CDDS_POSTPAINT, &nmlvcd);
|
notify_postpaint(infoPtr, &nmlvcd);
|
||||||
|
|
||||||
infoPtr->clrTextBk = oldClrTextBk;
|
infoPtr->clrTextBk = oldClrTextBk;
|
||||||
infoPtr->clrText = oldClrText;
|
infoPtr->clrText = oldClrText;
|
||||||
|
|
Loading…
Reference in New Issue