通过 Customdraw 为 ListView 添加颜色
实现一个 CListCtrl 控件派生类,可用于设置行、列、单元格的颜色。
引言
我正在学习 CustomDraw
。由于 MFC ListView
缺少颜色 :), 我写了这个小类,通过扩展 CListCtrl
,让您能够设置任何行、列、单元格的颜色。
此外,您可以使用任何两种颜色设置“网格模式”,这将自动为视图着色。还有一个“交替行模式”,可以让您自动设置交替行的颜色。还有一些其他功能,如“文本掩码模式”,它允许文本颜色根据单元格的背景颜色通过反转颜色来自动设置。
另一个人可能会觉得有用的一个功能是,即使插入了新行或删除了现有行,行/单元格的颜色也不会改变。这意味着删除第 2 行不会使第 3 行以第 2 行的颜色显示。尽管这听起来像是预期的行为,但一半的代码用于跟踪行和单元格 :(。
我需要所有这些功能来实现我的“宠物”项目。由于我找不到任何东西,我被迫编写了这个类。(MFC 死了吗 :(,这些天我很难找到新文章。)
除了要求我改进我的编码标准 :) 之外,欢迎提出意见/建议。
背景
我们需要捕获 NM_CUSTOMDRAW
通知才能设置背景颜色或文本颜色。在绘画的项预绘制阶段,我们需要请求子项绘画。与跟踪项目颜色所需的艰苦工作相比,这部分很简单。
本文的目的不是详细解释 NM_CUSTOMDRAW
,而是提供一个易于使用的类。如果您想详细了解自定义绘制,请阅读 这篇文章。
Using the Code
以下是可以使用的新方法。这些名称希望是不言自明的。“Clr”代表“清除”。因此 ClrRowColor()
如果已设置,则清除行颜色。 ResetColors()
会将所有内容重置为正常状态
void SetRowColor(COLORREF cf, long row);
void SetColColor(COLORREF cf, long col);
void SetCellColor(COLORREF cf, long row, long col);
void ClrRowColor(long row);
void ClrColColor(long col);
void ClrCellColor(long row,long col);
void SetGridMode(bool TurnOn,COLORREF x=0,COLORREF y=0);
void SetTextMask(bool TurnOn);
void SetAltRowColors(bool TurnOn,COLORREF x=0,COLORREF y=0);
void ResetColors(void);
对于 SetGridMode()
和 SetAltRowColors
,您可能需要试验 x 和 y 值以使视图看起来更好。
您必须记住,列颜色将覆盖行颜色。并且单元格颜色将优先于行、列颜色。 GridMode
和 AltRowMode
在行/列/单元格颜色方面将具有最低的优先级。您可以尝试看看我的意思。
要使用代码,请包含 "CColorListCtrl.h" 并使用 CColorListCtrl
类代替 CListCtrl
。

为了获得上述效果,我使用了
m_list1.SetRowColor(RGB(0,120,0),0);
m_list1.SetCellColor(RGB(153,102,102),2,1);
为了获得上述效果,我使用了
m_list1.SetGridMode(true,RGB(0,255,255),RGB(153,153,102));
为了获得上述效果,我使用了
m_list1.SetAltRowColors(true,RGB(0,255,255),RGB(153,153,102));
示例二、三已在“MaskMode
”开启的情况下运行,第一个在掩码模式关闭的情况下运行。您可以清楚地注意到差异。要设置掩码模式,您必须使用
m_list1.SetTextMask(true);
关注点
最烦人的部分是 OnPaint()
/UpdateWindow()
方法似乎没有更新 ListView
控件。所以我不得不求助于 RedrawWindow()
方法(在其中一篇文章中找到了关于这个方法的信息)。此外,我还没有测试过我的代码是否启用了排序选项。所以你可能需要自己找出答案。
历史
- 2008 年 3 月 5 日:初始发布