65.9K
CodeProject 正在变化。 阅读更多。
Home

通过 Customdraw 为 ListView 添加颜色

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.55/5 (10投票s)

2008 年 3 月 5 日

CPL

3分钟阅读

viewsIcon

99320

downloadIcon

4864

实现一个 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

rowCell.jpg

为了获得上述效果,我使用了

m_list1.SetRowColor(RGB(0,120,0),0);           
m_list1.SetCellColor(RGB(153,102,102),2,1);

Grid.jpg

为了获得上述效果,我使用了

m_list1.SetGridMode(true,RGB(0,255,255),RGB(153,153,102));

AltRows.jpg

为了获得上述效果,我使用了

m_list1.SetAltRowColors(true,RGB(0,255,255),RGB(153,153,102));

示例二、三已在“MaskMode”开启的情况下运行,第一个在掩码模式关闭的情况下运行。您可以清楚地注意到差异。要设置掩码模式,您必须使用

m_list1.SetTextMask(true);

关注点

最烦人的部分是 OnPaint()/UpdateWindow() 方法似乎没有更新 ListView 控件。所以我不得不求助于 RedrawWindow() 方法(在其中一篇文章中找到了关于这个方法的信息)。此外,我还没有测试过我的代码是否启用了排序选项。所以你可能需要自己找出答案。

历史

  • 2008 年 3 月 5 日:初始发布
© . All rights reserved.