在使用MFC时,常常会用到CListCtrl控件,有时候还会需要它能在不同的情况下,字体颜色和背景颜色会发生变化,但是CListCtrl并不支持,这个时候我们就需要自己写一个CListCtrl类去实现额外的功能了。
首先我们需要添加一个类让它去继承CListCtrl类,然后将我们需要实现的功能添加进这个新的类中。
//字体颜色结构体
struct ItemColor
{
int m_iRow;
int m_iCol;
COLORREF m_TextColor;
};
class CListCtrlP :public CListCtrl
{
public:
CListCtrlP();
~CListCtrlP();
protected:
DECLARE_MESSAGE_MAP()
public:
//重新绘制的方法
afx_msg void OnNMCustomdraw(NMHDR *pNMHDR,LRESULT *pResult);
//设置颜色
void SetColor(int iRow, int iCol, COLORREF color);
//清空
void ClearColor();
private:
//用于保存某一行某一列的字体颜色
std::vector<ItemColor> m_itemColors;
COLORREF m_TextColor;
};
首先需要将需要设置颜色的单元格信息保存起来。
void CListCtrlP::SetColor(int iRow, int iCol, COLORREF color)
{
ItemColor itemColor;
itemColor.m_iRow = iRow;
itemColor.m_iCol = iCol;
itemColor.m_TextColor = color;
m_itemColors.push_back(itemColor);
}
void CListCtrlP::ClearColor()
{
m_itemColors.clear();
}
然后再OnNMCustomdraw中让它将该单元格中的字体颜色按照我们保存的去显示。
void CListCtrlP::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
*pResult = CDRF_DODEFAULT;
if (CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if (CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
{
*pResult = CDRF_NOTIFYSUBITEMDRAW;
}
//当pLVCD结构体中nmcd成员的dwDrawStage状态为CDDS_ITEMPREPAINT | CDDS_SUBITEM时,我们就可以根据行和列去设置
else if ((CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
{
//先将字体颜色和背景颜色设为系统默认
pLVCD->clrTextBk = 16777215;
pLVCD->clrText = 0;
//遍历字体颜色表
for (int i = 0; i < m_itemColors.size(); i++)
{
//判断该行中是否存在需要改变颜色的单元格
if ( m_itemColors[i].m_iRow == pLVCD->nmcd.dwItemSpec)
{
//设置单元格背景颜色,我这里是默认将一整行都设为分红色
//如果需要设为其他颜色,或者单独设置某一单元格的颜色,可以效仿字体颜色的方式去添加
pLVCD->clrTextBk = RGB(255,228,225);
//判断该单元格字体是否需要改变颜色
if (m_itemColors[i].m_iCol == pLVCD->iSubItem)
{
pLVCD->clrText = m_itemColors[i].m_TextColor;
break;
}
}
}
*pResult = CDRF_DODEFAULT;
}
}
//创建一个对象
CListCtrlP list1;
//往list1中添加数据
....
//设置字体颜色
m_listSource.SetColor(iRow, iCol, RGB(255, 0, 0));