您的位置:首页 > 其它

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

2013-01-12 11:59 357 查看
有时可能需要设置某行的文字为特殊颜色,以表示某种特殊含义,如有些为警告信息,有些为普通信息。

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

lpNMCustomDrawLong 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.

ControlStructure
List viewNMLVCUSTOMDRAW
ToolTipsNMTTCUSTOMDRAW
Tree viewNMTVCUSTOMDRAW
All other supported controlsNMCUSTOMDRAW


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_DODEFAULTThe control will draw itself. It will not send any additional NM_CUSTOMDRAW messages for this paint cycle.CDRF_NOTIFYITEMDRAWThe control will notify the parent of any item-related drawing operations. It will send NM_CUSTOMDRAW messages before and after drawing items.CDRF_NOTIFYITEMERASEThe control will notify the parent when an item will be erased. It will send NM_CUSTOMDRAW messages before and after erasing items.CDRF_NOTIFYPOSTERASEThe control will notify the parent after erasing an item.CDRF_NOTIFYPOSTPAINTThe control will notify the parent after painting an item.

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

CDRF_NEWFONTYour 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_SKIPDEFAULTYour 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;

//………………

}

②其中,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.

ValueMeaning
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 dwItemSpec, uItemState, 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,表示我们不再需要其他特殊的消息了,默认执行即可。

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: