大家也许熟悉WM_NOTIFY,控件通过WM_NOTIFY向父窗口发送消息。在WM_NOTIFY消息体中,部分控件会发送NM_CUSTOMDRAW告诉父窗口自己需要绘图。

也可以反射NM_CUSTOMDRAW消息,如:

ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)         //需要自己加进去
afx_msg void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult);

参数:

pNMHDR 说到底只是一个指针,大多数情况下它指向一个NMHDR结构对象,NMHDR结构如下:

typedef struct tagNMHDR
{
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;

其中:

hwndFrom 发送方控件的窗口句柄

idFrom 发送方控件的ID

code 通知代码

对于某些控件来说,pNMHDR则会解释成其它内容更丰富的结构对象的指针,如:对于列表控件来说,pNMHDR常常指向一个NMCUSTOMDRAW对象,NMCUSTOMDRAW结构如下:

typedef struct tagNMCUSTOMDRAWINFO
{
NMHDR hdr;
DWORD dwDrawStage;
HDC hdc;
RECT rc;
DWORD dwItemSpec;
UINT uItemState;
LPARAM lItemlParam;
} NMCUSTOMDRAW, FAR * LPNMCUSTOMDRAW;

其中:

hdr NMHDR对象

dwDrawStage 当前绘制状态,其取值如下:

CDDS_POSTERASE 擦除循环结束
CDDS_POSTPAINT  绘制循环结束
CDDS_PREERASE  准备开始擦除循环
CDDS_PREPAINT 准备开始绘制循环
CDDS_ITEM 指定dwItemSpec, uItemState, lItemlParam参数有效
CDDS_ITEMPOSTERASE 列表项擦除结束
CDDS_ITEMPOSTPAINT  列表项绘制结束
CDDS_ITEMPREERASE 准备开始列表项擦除
CDDS_ITEMPREPAINT 准备开始列表项绘制
CDDS_SUBITEM 指定列表子项

hdc指定了绘制操作所使用的设备环境。

rc指定了将被绘制的矩形区域。

dwItemSpec 列表项的索引

uItemState 当前列表项的状态,其取值如下:

CDIS_CHECKED 标记状态
CDIS_DEFAULT 默认状态
CDIS_DISABLED 禁止状态
CDIS_FOCUS 焦点状态
CDIS_GRAYED 灰化状态
CDIS_SELECTED 选中状态
CDIS_HOTLIGHT 热点状态
CDIS_INDETERMINATE 不定状态
CDIS_MARKED标注状态  

lItemlParam 当前列表项的绑定数据

pResult 指向状态值的指针,指定系统后续操作,依赖于dwDrawStage:

当dwDrawStage为CDDS_PREPAINT,pResult含义如下:

CDRF_DODEFAULT 默认操作,即系统在列表项绘制循环过程不再发送NM_CUSTOMDRAW
CDRF_NOTIFYITEMDRAW  指定列表项绘制前后发送消息
CDRF_NOTIFYPOSTERASE 列表项擦除结束时发送消息
CDRF_NOTIFYPOSTPAINT 列表项绘制结束时发送消息

当dwDrawStage为CDDS_ITEMPREPAINT,pResult含义如下:

CDRF_NEWFONT  指定后续操作采用应用中指定的新字体
CDRF_NOTIFYSUBITEMDRAW  列表子项绘制时发送消息
CDRF_SKIPDEFAULT  系统不必再绘制该子项

以下是一个利用NM_CUSTOMDRAW消息绘制出的多色列表框的例子:

对应代码如下:

void CCoolList::OnCustomDraw  //从CListCtrl派生(NMHDR *pNMHDR, LRESULT *pResult)
{
//类型安全转换
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
*pResult = 0; //指定列表项绘制前后发送消息
if(CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
{
//奇数行
if(pLVCD->nmcd.dwItemSpec % 2)
pLVCD->clrTextBk = RGB(255, 255, 128);
//偶数行
else
pLVCD->clrTextBk = RGB(128, 255, 255);
//继续
*pResult = CDRF_DODEFAULT;
}
}
注意到上例采取了3.1所推荐的第2种实现方法,派生了一个新类CCoolList。

总体步骤:

  1. 派生CCoolList类
  2. BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
     //{{AFX_MSG_MAP(CMyListCtrl)
      // NOTE - the ClassWizard will add and remove mapping macros here.
    ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)  //自己添加
     //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
  3. 定义CListCtrl  Control m_list变量,再将CListCtrl 改为CCoolList

改变ListCtrl某行的背景色或者字体颜色的更多相关文章

  1. Eclipse详细设置护眼背景色和字体颜色并导出

    Eclipse详细设置护眼背景色和字体颜色并导出 Eclipse是一款码农们喜闻乐见的集成开发平台,但是其默认的主题和惨白的背景色实在是太刺激眼球了.下面,将给大家详细介绍如何设置成护眼主题的方法,也 ...

  2. ASP.Net ListBox DropdownList 不同条目设置背景色和字体颜色( 转· 载 )

    ASP.Net ListBox DropdownList 不同条目设置背景色和字体颜色 2009-09-30  来自:真有意思 [ZU14.CN]  字体大小:[大 中 小] 摘要:在HTML展现页面 ...

  3. C# 控制台程序(命令行程序)设置字体颜色,窗口宽高,光标行数

    控制台程序(命令行程序)设置窗口宽度高度,如下代码: Console.WriteLine(Console.WindowHeight); Console.WriteLine(Console.Buffer ...

  4. UITableViewCell背景色.选中背景色,分割线,字体颜色设置

    1.系统默认的颜色设置 //无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionStyle = ...

  5. [Eclipse] 详细设置护眼背景色和字体颜色并导出

    http://jingyan.baidu.com/article/d5a880eb6c4f7813f147ccef.html Eclipse是一款码农们喜闻乐见的集成开发平台,但是其默认的主题和惨白的 ...

  6. Android沉浸式状态栏背景色以及字体颜色的修改

    在activity中设置透明状态栏 的思路:    1.让activity的布局全屏 此时布局会和状态栏重叠        2.让布局最上方预留出和状态栏高度一样的高度,将状态栏的背景色设置为透明 效 ...

  7. iOS改变UIAlertView、UIActionSheet、UIAlertController系统字体颜色

    废话不多说,直接上代码,效果是最好的说服力 1.改变UIAlertView字体颜色 [UIView appearance].tintColor = [UIColor greenColor]; 个人还是 ...

  8. element UI table show-overflow-tooltip属性更改背景色和字体颜色

    .el-tooltip__popper { width: 80%;/*修改宽度*/ background: #000 !important;/*背景色  !important优先级*/ opacity ...

  9. Linux用命令设置终端背景色和字体颜色

    用命令改 1.setterm -inversecreen on 背景字体颜色互换 2.setterm -inversecreen on 恢复默认 3.setterm -[选项] [参数] |-back ...

随机推荐

  1. Objective-C语法汇总

    1.方法前的加减号 Objective-C中是没有public与private的概念的,即可以认为全部都是public.减号表示的是一个函数.方法.消息的开始.加号则表示不需要创建一个类的实例,其他类 ...

  2. ruby 字符串学习笔记3

    ascii转字符或者字符串转ascii "a".ord # => 97 "!".ord # => 33 "\n".ord # = ...

  3. jdk之jhat命令

    jhat命令 -- JavaHeap Analyse Tool 用途:是用来分析Java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言第一步:导出堆  ...

  4. Java SE 第十讲---面向对象特征之封装2

    1.类中的属性又叫做成员变量(member variable),属性用英文表示为property或者attitude 2.对象(Object)又叫做实例(Instance),生成一个对象的过程又叫做类 ...

  5. delphi Pointer 转成string

    var  s: string;  p: pointer;  s := PChar(p);前提p指向的字符串要以#0结尾.

  6. (easy)LeetCode 242.Valid Anagram

    Given two strings s and t, write a function to determine if t is an anagram of s. For example,s = &q ...

  7. JDialog窗体

    class MyJDialog extends JDialog{    public MyJDialog(JFrame frame){    super(frame,"第一个Dialog窗体 ...

  8. ORACLE错误一览表【转】

    http://blog.itpub.net/26892340/viewspace-722178/

  9. spi驱动无法建立spidev问题

    参考这里: http://e2e.ti.com/support/arm/sitara_arm/f/791/t/168122.aspx http://communistcode.co.uk/blog/b ...

  10. 在虚拟机上安装红帽Linux.5.5.for.x86.服务器版系统(按针对安装oracle 10g作的配置)

    在虚拟机上安装红帽Linux.5.5.for.x86.服务器版系统(按针对安装oracle 10g作的配置)   软件版本: 虚拟机版本:vmwareworkstation 7.11 build-28 ...