双色球万能组合10码:NM_CUSTOMDRAW消息解释
来源:百度文库 编辑:中财网 时间:2024/04/29 13:33:30
ON_NOTIFY ( NM_CUSTOMDRAW, IDC_MY_LIST, OnCustomdrawMyList )
处理函数的原形如下:afx_msg void OnCustomdrawMyList ( NMHDR* pNMHDR, LRESULT* pResult );
这就告诉MFC你要处理从你的ListCtrl控件发出的WM_NOTIFY消息,ID为IDC_MY_LIST,通知码为NM_CUSTOMDRAW,OnCustomdrawMyList就是你的处理函数。 如果你有一个从ClistCtr派生的类,你想为它添加custom draw,你就可以使用ON_NOTIFY_REFLECT来代替。如下:ON_NOTIFY_REFLECT ( NM_CUSTOMDRAW, OnCustomdraw )OnCustomdraw的原形和上面的函数一致,但它是声明在你的派生类里的。
Custom draw将控件的绘制分为两部分:擦除和绘画。Windows在每部分的开始和结束都会发送NM_CUSTOMDRAW消息。所以总共就有4个消息。但是实际上你的程序所收到消息可能就只有1个或者多于四个,这取决于你想要让WINDOWS怎么做。每次发送消息的时段被称作为一个“绘画段”。你必须紧紧抓住这个概念,因为它贯穿于整个“重绘”的过程。 所以,你将会在以下的时间点收到通知:l 一个item被画之前——“绘画前”段l 一个item被画之后——“绘画后”段l 一个item被擦除之前——“擦除前”段l 一个item被擦除之后——“擦除后”段
并不是所有的消息都是一样有用的,实际上,我不需要处理所有的消息,直到这篇文章完成之前,我还没使用过擦除前和擦除后的消息。所以,不要被这些消息吓到你。NM_CUSTOMDRAW Messages提供给你的信息:
l NM_CUSTOMDRAW消息将会给你提供以下的信息:l ListCtrl的句柄l ListCtrl的IDl 当前的“绘画段”l 绘画的DC,让你可以用它来画画l 正在被绘制的控件、item、subitem的RECT值l 正在被绘制的Item的Index值l 正在被绘制的SubItem的Index值l 正被绘制的Item的状态值(selected, grayed,等等)l Item的LPARAM值,就是你使用CListCtrl::SetItemData所设的那个值
上述所有的信息对你来说可能都很重要,这取决于你想实现什么效果,但最经常用到的就是“绘画段”、“绘画DC”、“Item Index”、“LPARAM”这几个值。一个简单的例子:
好了,经过上面的无聊的细节之后,我们是时候来看一些简单的代码了。第一个例子非常的简单,它只是改变了一下控件中文字的颜色。 处理的代码如下:void CPanel1::OnCustomdrawList ( NMHDR* pNMHDR, LRESULT* pResult ){
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast
// Take the default processing unless we set this to something else below.
*pResult = 0; // First thing - check the draw stage. If it's the control's prepaint
// stage, then tell Windows we want messages for every item.
if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
{
// This is the prepaint stage for an item. Here's where we set the
// item's text color. Our return value will tell Windows to draw the
// item itself, but it will use the new color we set here.
// We'll cycle the colors through red, green, and light blue.
COLORREF crText; if ( (pLVCD->nmcd.dwItemSpec % 3) == 0 )
crText = RGB(255,0,0);
else if ( (pLVCD->nmcd.dwItemSpec % 3) == 1 )
crText = RGB(0,255,0);
else
crText = RGB(128,128,255); // Store the color back in the NMLVCUSTOMDRAW struct.
pLVCD->clrText = crText; // Tell Windows to paint the control itself.
*pResult = CDRF_DODEFAULT;
}
}结果如下,你可以看到行和行间的颜色的交错显示,多酷,而这只需要两个if的判断就可以做到了。
一个更小的简单例子: 下面的例子将演示怎么去处理subitem的绘画(其实subitem也就是列)在ListCtrl控件绘画前处理NM_CUSTOMDRAW消息。告诉Windows我们想对每个Item处理NM_CUSTOMDRAW消息。当这些消息中的一个到来,告诉Windows我们想在每个SubItem的绘制前处理这个消息当这些消息到达,我们就为每个SubItem设置文字和背景的颜色。
这里需要注意两件事:l clrTextBk的颜色只是针对每一列,在最后一列的右边那个区域颜色也还是和ListCtrl控件的背景颜色一致。l 当我重新看文档的时候,我注意到有一篇题目是“NM_CUSTOMDRAW(list view)”的文章,它说你可以在最开始的custom draw消息中返回CDRF_NOTIFYSUBITEMDRAW就可以处理SubItem了,而不需要在CDDS_ITEMPREPAINT绘画段中去指定CDRF_NOTIFYSUBITEMDRAW。但是我试了一下,发现这种方法并不起作用,你还是需要处理CDDS_ITEMPREPAINT段。