If you do not want to go through the hassle implementing OwnerDraw list controls, where you got to code a bunch of stuff inside the DrawItem override, then you can use the CustomDraw handler. With version 4.70 of the Comctrl.dll, you can handle row data, but with the 4.72+ version of the Dll, you can handle cell data. Which opens a lot of possibilities.
Here I present some examples on how to use the CustomDraw message.
Note: Similar handling is also possible for the other common controls.
Add the following to your CListCtrl derived class header file:
afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
void CListCtrlEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
switch(lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
*pResult = CDRF_DODEFAULT;
int iRow = lplvcd->nmcd.dwItemSpec;
if(iRow & 1)
{
lplvcd->clrTextBk = RGB(255, 0, 0);
lplvcd->clrText = RGB(255, 255, 0);
*pResult = CDRF_NEWFONT;
}
break;
default:
*pResult = CDRF_DODEFAULT;
}
}
void CListCtrlEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
switch(lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYSUBITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
*pResult = CDRF_NOTIFYSUBITEMDRAW;
break;
case CDDS_ITEMPREPAINT|CDDS_SUBITEM:
{
*pResult = CDRF_DODEFAULT;
int iCol = lplvcd->iSubItem;
int iRow = lplvcd->nmcd.dwItemSpec;
if((iRow & 1) && (iCol & 1))
{
lplvcd->clrTextBk = RGB(255, 0, 0);
lplvcd->clrText = RGB(255, 255, 0);
*pResult = CDRF_NEWFONT;
}
break;
}
default:
*pResult = CDRF_DODEFAULT;
}
}
void CListCtrlEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
switch(lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYSUBITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
*pResult = CDRF_NOTIFYSUBITEMDRAW;
if(GetExtendedStyle() & LVS_EX_CHECKBOXES)
{
*pResult = CDRF_DODEFAULT;
int iRow = lplvcd->nmcd.dwItemSpec;
if(GetCheck(iRow))
{
lplvcd->clrTextBk = RGB(255, 0, 0);
lplvcd->clrText = RGB(255, 255, 0);
*pResult = CDRF_NEWFONT;
}
}
break;
case CDDS_ITEMPREPAINT|CDDS_SUBITEM:
{
*pResult = CDRF_DODEFAULT;
int iCol = lplvcd->iSubItem;
int iRow = lplvcd->nmcd.dwItemSpec;
if((iRow & 1) && (iCol & 1))
{
lplvcd->clrTextBk = RGB(255, 0, 0);
lplvcd->clrText = RGB(255, 255, 0);
*pResult = CDRF_NEWFONT;
}
break;
}
default:
*pResult = CDRF_DODEFAULT;
}
}
void CListCtrlEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
switch(lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYSUBITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
*pResult = CDRF_NOTIFYSUBITEMDRAW;
break;
case CDDS_ITEMPREPAINT|CDDS_SUBITEM:
{
int iCol = lplvcd->iSubItem;
int iRow = lplvcd->nmcd.dwItemSpec;
CString sItem = GetItemText(iRow, iCol);
CRect rc;
GetCellRect(iRow, iCol, LVIR_BOUNDS, rc);
CDC *pDC= CDC::FromHandle(lplvcd->nmcd.hdc);
pDC->DrawText(sItem , rc, DT_CENTER);
*pResult= CDRF_SKIPDEFAULT;
break;
}
default:
*pResult = CDRF_DODEFAULT;
}
}
Where GetCellRect is defined as follows:
BOOL CListCtrlEx::GetCellRect(int iRow, int iCol, int nArea, CRect &rect)
{
if(iCol)
return GetSubItemRect(iRow, iCol, nArea, rect);
if(GetColumnCount()== 1)
return GetItemRect(iRow, rect, nArea);
iCol = 1;
CRect rCol1;
if(!GetSubItemRect(iRow, iCol, nArea, rCol1))
return FALSE;
if(!GetItemRect(iRow, rect, nArea))
return FALSE;
rect.right = rCol1.left;
return TRUE;
}
author: Navi Singh