About Custom Draw /MFC

Custom Draw不是一个通用控件,而是一个许多控件提供的服务。用于定制控件的外观。

通常以下控件支持Custom Draw功能

  • Header controls
  • List-view controls
  • Rebar controls
  • Toolbar controls
  • ToolTip controls
  • Trackbar controls
  • Tree-view controls
  • (杯具,我是查找修改CSliderCtrl的办法找到的)

控件在绘制操作的特殊时间发送NM_CUSTOMDRAW通知消息,NM_CUSTOMDRAW通知作为WM_NOTIFY消息发送。

根据系统或者其他应用程序的消息,通用控件周期性地绘制删除自己。

控件绘制或者删除自己的过程叫做paint cycle。


支持custom draw 的控件在每个paint cycle 周期性地发送NM_CUSTOMDRAW通知消息,这个消息一般伴随在

NMCUSTOMDRAW结构体中或者把NMCUSTOMDRAW结构体作为第一个成员的其他结构体中。

NMCUSTOMDRAW结构体的一个成员dwDrawStage代表paint cycle的当前状态。

控件有四个基本绘制状态可以通知它的所属,如下:

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

Global draw stage values Description
CDDS_PREPAINT           Before the paint cycle begins.


CDDS_POSTPAINT        After the paint cycle is complete.


CDDS_PREERASE           Before the erase cycle begins.


CDDS_POSTERASE        After the erase cycle is complete.

------------------------------------------------------------------------------------------------------
上面的每个值可以和以下CDDS_ITEM标志组合描述具体item的绘制状态。

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

Item-specific                   draw stage values Description
CDDS_ITEMPREPAINT        Before an item is drawn.


CDDS_ITEMPOSTPAINT      After an item has been drawn.


CDDS_ITEMPREERASE        Before an item is erased.


CDDS_ITEMPOSTERASE      After an item has been erased.


CDDS_SUBITEM               Shell and Common Controls Versions 4.71. Flag combined with CDDS_ITEMPREPAINTor CDDS_ITEMPOSTPAINT if a subitem is                                         being drawn. This will only be set if CDRF_NOTIFYITEMDRAW is returned from CDDS_PREPAINT.

----------------------------------------------------------------------------------------------------------
应用程序必须处理NM_CUSTOMDRAW通知消息然后回复一个特殊值告诉控件该做什么。

每个paint cycle开始后,控件发送NM_CUSTOMDRAW通知消息,此时NMCUSTOMDRAW结构体

的dwDrawStage成员描述为CDDS_PREPAINT。你的应用程序返回的值指定控件在什么时候如何发送

paint cycle后续的绘制消息。你的应用程序可以发送下面标志位的组合:

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

Return value Effect
CDRF_DODEFAULT                  The control will draw itself. It will not send additional NM_CUSTOMDRAW notifications for this paint cycle. This flag cannot                                              be used with any other flag.


CDRF_NOTIFYITEMDRAW         The control will notify the parent of any item-specific drawing operations. It will send NM_CUSTOMDRAW notification                                                     messages before and after it draws items.


CDRF_NOTIFYPOSTPAINT         The control will send an NM_CUSTOMDRAW notification when the painting cycle for the entire control is complete.


CDRF_SKIPDEFAULT                 The control will not perform any painting at all.


CDRF_DOERASE                      The control will only draw the background.


CDRF_SKIPPOSTPAINT             The control will not draw the focus rectangle around an item.

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

如果你的应用程序为custom draw 的首个prepaint返回CDRF_NOTIFYITEMDRAW,控件会为paint cycle中他绘制的每个item发送通知,这些通知将NMCUSTOMDRAW结构体的dwDrawStage成员设置为CDDS_ITEMPREPAINT。

当控件结束这个item的时候,你可以返回CDRF_NOTIFYPOSTPAINT要求控件发送其他的通知。

返回CDRF_DODEFAULT,控件开始绘制下个item的时候才通知它的父窗口。

原文地址:https://www.cnblogs.com/ezhong/p/2171496.html