有时可能需要设置某行的文字为特殊颜色,以表示某种特殊含义,如有些为警告信息,有些为普通信息。
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 消息,该消息的消息响应函数为
- void CXXXX::OnNMCustomdrawXXXX(NMHDR *pNMHDR, LRESULT *pResult)
- {
- LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
- // TODO: Add your control notification handler code here
- *pResult = CDRF_DODEFAULT;
- //………………
- }
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 |
---|---|
| |
| After the erasing cycle is complete. |
| After the painting cycle is complete. |
| Before the erasing cycle begins. |
| Before the painting cycle begins.
|
| |
| Indicates that the dwItemSpec, uItemState, and lItemlParam members are valid. |
| After an item has been erased. |
| After an item has been drawn. |
| Before an item is erased. |
| Before an item is drawn. |
| 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. |
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,表示我们不再需要其他特殊的消息了,默认执行即可。
- void CXXXX::OnNMCustomdrawXXXX(NMHDR *pNMHDR, LRESULT *pResult)
- {
- LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
- *pResult = CDRF_DODEFAULT;
- // First thing - check the draw stage. If it's the control's pre-paint 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 notification message for an item.
- //处理,将item改变背景颜色
- if( /*符合条件*/ )
- pLVCD->clrText = RGB(255,0,255);
- *pResult = CDRF_DODEFAULT;
- }
- }
上面谈的方法主要用于设置静态字体颜色,当然,如果你的列表的信息在不断变化(即用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