动态设置不同的行字体颜色

有时可能需要设置某行的文字为特殊颜色,以表示某种特殊含义,如有些为警告信息,有些为普通信息。


NM_CUSTOMDRAW   ------http://msdn.microsoft.com/en-us/library/ms930820.aspx

NM_CUSTOMDRAW
#ifdef LIST_VIEW_CUSTOM_DRAW
  lpNMCustomDraw = (LPNMLVCUSTOMDRAW) lParam;
#elif TOOL_TIPS_CUSTOM_DRAW
  lpNMCustomDraw = (LPNMTTCUSTOMDRAW) lParam;
#elif TREE_VIEW_CUSTOM_DRAW
  lpNMCustomDraw = (LPNMTVCUSTOMDRAW) lParam;
#else
  lpNMCustomDraw = (LPNMCUSTOMDRAW) lParam;
#endif


Parameters
lpNMCustomDraw
Long pointer to a custom draw-related structure that contains information about the drawing operation. The following table lists the controls that send the NM_CUSTOMDRAW message and their associated structures.
Control Structure
List view NMLVCUSTOMDRAW
ToolTips NMTTCUSTOMDRAW
Tree view NMTVCUSTOMDRAW
All other supported controls NMCUSTOMDRAW
Return Values

The value your application can return depends on the current drawing stage. The dwDrawStage member of the associated NMCUSTOMDRAW structure holds a value that specifies the drawing stage.

You must return one of the following values when dwDrawStage equals CDDS_PREPAINT:

CDRF_DODEFAULT
The control will draw itself. It will not send any additional NM_CUSTOMDRAW messages for this paint cycle.
CDRF_NOTIFYITEMDRAW
The control will notify the parent of any item-related drawing operations. It will send NM_CUSTOMDRAW messages before and after drawing items.
CDRF_NOTIFYITEMERASE
The control will notify the parent when an item will be erased. It will send NM_CUSTOMDRAW messages before and after erasing items.
CDRF_NOTIFYPOSTERASE
The control will notify the parent after erasing an item.
CDRF_NOTIFYPOSTPAINT
The control will notify the parent after painting an item.

You must return one of the following values when dwDrawStage equals CDDS_ITEMPREPAINT:

CDRF_NEWFONT
Your application specified a new font for the item; the control will use the new font. For more information on changing fonts, see  Changing Fonts and Colors.
CDRF_SKIPDEFAULT
Your application drew the item manually. The control will not draw the item.
Remarks

Currently header, list view, rebar, toolbar, ToolTip, trackbar, and tree view controls support custom draw functionality. The ToolTip control supports custom draw for Microsoft® Windows® CE .NET.

---------------------------------------------------------------------------------------------------------------------------------------------



① 当控件绘制时,会发送NM_CUSTOMDRAW 消息,该消息的消息响应函数为

  1. void CXXXX::OnNMCustomdrawXXXX(NMHDR *pNMHDR, LRESULT *pResult)  
  2. {  
  3.     LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);  
  4.     // TODO: Add your control notification handler code here  
  5.     *pResult = CDRF_DODEFAULT;  
  6.        //………………  
  7.  }  
②其中, pNMHDR为输入参数 ,其指向 NMLVCUSTOMDRAW 结构体,该结构包含了很多信息,包括字体颜色、背景等等,特别是第一个成员,为 NMCUSTOMDRAW 结构体变量,

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

其包含了Current drawing stage

dwDrawStage

Type: DWORD

The current drawing stage. This is one of the following values.

Value Meaning
Global Values:
 
CDDS_POSTERASE

After the erasing cycle is complete.

CDDS_POSTPAINT

After the painting cycle is complete.

CDDS_PREERASE

Before the erasing cycle begins.

CDDS_PREPAINT

Before the painting cycle begins.

Item-specific Values:
 
CDDS_ITEM

Indicates that the dwItemSpecuItemState, and lItemlParam members are valid.

CDDS_ITEMPOSTERASE

After an item has been erased.

CDDS_ITEMPOSTPAINT

After an item has been drawn.

CDDS_ITEMPREERASE

Before an item is erased.

CDDS_ITEMPREPAINT

Before an item is drawn.

CDDS_SUBITEM

Version 4.71. Flag combined with CDDS_ITEMPREPAINT or CDDS_ITEMPOSTPAINT if a subitem is being drawn. This will only be set ifCDRF_NOTIFYITEMDRAW is returned from CDDS_PREPAINT.

③  pResult为输出参数 ,该参数决定了接下来向windows发送什么消息(与绘制有关的),通过发送该消息我们可以进入下一步需要的处理阶段。

typedef struct tagNMLVCUSTOMDRAW {
  NMCUSTOMDRAW nmcd;
  COLORREF clrText;
  COLORREF clrTextBk;
  #if (_WIN32_IE >= 0x0400)
    int iSubItem;
  #endif
  DWORD dwItemType;
  RECT rcText;
  UINT uAlign;
} NMLVCUSTOMDRAW, *LPNMLVCUSTOMDRAW;

④ 有一点必须注意(英文的,我觉得看起来比翻译过来更精确):

     One thing to keep in mind is you must always check the draw stage before doing anything else, because your handler will receive many messages, and the draw stage determines what action your code takes.

如何修改某一行的字体颜色:

①  首先,我们应该明白要修改字体颜色,应该在pre-paint 阶段来完成

② 因此,在消息响应函数中,我们首先判断是否处于pre-paint stage(即pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT),然后通过修改输出值pResult 的值来通知windows我们需要处理每个item的消息(即设置 *pResult = CDRF_NOTIFYITEMDRAW)。

③ 再次进入消息响应函数时,我们判断是否处于Item的pre-paint stage(即pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT),如果是则进行相关处理,即修改字体颜色等等。

④ 处理完了后重新设置 *pResult = CDRF_DODEFAULT,表示我们不再需要其他特殊的消息了,默认执行即可。

  1. void CXXXX::OnNMCustomdrawXXXX(NMHDR *pNMHDR, LRESULT *pResult)  
  2. {  
  3.     LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);  
  4.     *pResult = CDRF_DODEFAULT;  
  5.   
  6.     // First thing - check the draw stage. If it's the control's pre-paint stage,   
  7.     // then tell Windows we want messages for every item.  
  8.     if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )  
  9.     {  
  10.         *pResult = CDRF_NOTIFYITEMDRAW;  
  11.     }  
  12.     else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )  
  13.     {  
  14.         // This is the notification message for an item.   
  15.     //处理,将item改变背景颜色  
  16.         if/*符合条件*/ )  
  17.         pLVCD->clrText = RGB(255,0,255);  
  18.           
  19.            *pResult = CDRF_DODEFAULT;  
  20.     }  
  21. }  

上面谈的方法主要用于设置静态字体颜色,当然,如果你的列表的信息在不断变化(即用SetItemText不断修改),那么也就实现了动态改变了,否则需要在合适的地方调用重绘函数:

                         BOOL RedrawItems( int nFirst, int nLast )

表示在nFirst和nLast之间的行需要进行重绘。

--------------------------------------------------------------------------------------------------------------

一篇不错的参考

http://www.codeproject.com/Articles/79/Neat-Stuff-to-Do-in-List-Controls-Using-Custom-Dra

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值