Visual C++2005中开发自定义绘图控件之二
来源:互联网 发布:轮毂数据计算器 编辑:程序博客网 时间:2024/05/22 10:55
指定处理所需的绘制阶段
正如我在前面提到的,绘制一个控件存在一些“阶段”。特别是,您可以将绘制过程理解为一系列阶段,其中控件通知其父窗口需要绘制的内容。事实上,控件甚至会在绘制控件及其各项前后发送一个通知,从而让编程人员更好地控制该过程。
在所有情况下,单一的 NM_CUSTOMDRAW 处理程序在每个绘制阶段都进行调用。然而,谨记:自定义绘制允许您在自己的绘制中合并默认的控件绘制,您需要指定您将处理哪个绘制阶段。这通过设置 NM_CUSTOMDRAW 处理程序的第二个参数 (pResult) 完成。事实上,如果您从未设置该值,则用初始阶段的 CDDS_PREPAINT 调用函数后,您的函数将不再被调用!
从技术上讲,只有两个阶段指定需要的绘制阶段(CDDS_PREPAINT 和 CDDS_ITEMPREPAINT),它们影响发送通知消息的内容。然而,通常只在处理程序的最后指定代码将处理的绘制阶段。表 2 列出用于指定所需绘制阶段(代码关注的)的值。
表 2:自定义绘制返回标志
自定义绘制返回标志 含义 CDRF_DEFAULT 指示控件自行绘制。该值为默认值,不应该将它与其他值组合在一起。 CDRF_SKIPDEFAULT 用于指定控件根本不进行任何绘制。 CDRF_NEWFONT 当代码更改绘制项/子项的字体时使用。 CDRF_NOTIFYPOSTPAINT 使通知信息在控件或每个项/子项绘制后发送。 CDRF_NOTIFYITEMDRAW 指出项(或子项)将进行绘制。注意,它下面的值与 CDRF_NOTIFYSUBITEMDRAW 相同。 CDRF_NOTIFYSUBITEMDRAW 指出子项(或项)将进行绘制。注意,它下面的值与 CDRF_NOTIFYITEMDRAW 相同。 CDRF_NOTIFYPOSTERASE 当删除控件后需要通知代码时使用。
以下为一个示例,其中的代码指定,当绘制控件的项 (CDRF_NOTIFYITEMDRAW) 及子项 (CDRF_NOTIFYPOSTPAINT),以及绘制完成时,应该调用 NM_CUSTOMDRAW 处理程序。
void CListCtrlWithCustomDraw::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR);
...
*pResult = 0; // Initialize value
*pResult |= CDRF_NOTIFYITEMDRAW;
*pResult |= CDRF_NOTIFYSUBITEMDRAW;
*pResult |= CDRF_NOTIFYPOSTPAINT;
}
筛选指定的绘制阶段
一旦指定要关注的阶段后,您需要处理这些阶段。因为绘制过程的每个阶段只有一个消息要发送,惯例是执行一个 switch 语句以决定准确的绘制阶段。不同的绘制阶段由以下标志定义:
CDDS_PREPAINT
CDDS_ITEM
CDDS_ITEMPREPAINT
CDDS_ITEMPOSTPAINT
CDDS_ITEMPREERASE
CDDS_ITEMPOSTERASE
CDDS_SUBITEM
CDDS_POSTPAINT
CDDS_PREERASE
CDDS_POSTERASE
对于一个 CListCtrl 派生的类,有一个 NM_CUSTOMDRAW 处理程序的示例,其中您可以发现,代码决定当前绘制阶段的方式:
void CMyCustomDrawControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR);
switch(pNMCD->dwDrawStage)
{
case CDDS_PREPAINT:
...
break;
case CDDS_ITEMPREPAINT:
...
break;
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
...
break;
...
}
*pResult = 0;
}
注意,为了决定子项(例如,列表视图控件)绘制的阶段,您必需使用按位 or 操作符,它有两个值:其中一个为 CDDS_ITEMPREPAINT 或者 CDDS_ITEMPOSTPAINT,另一个为 CDDS_SUBITEM。
要说明它,我们假定您想在绘制列表视图项之前进行一些处理。将编写 switch 语句来处理 CDDS_ITEMPREPAINT。
case CDDS_ITEMPREPAINT:
...
break;
然而,如果是您所关注子项的预绘制阶段,则将如下操作:
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
...
break;
正如我在前面提到的,绘制一个控件存在一些“阶段”。特别是,您可以将绘制过程理解为一系列阶段,其中控件通知其父窗口需要绘制的内容。事实上,控件甚至会在绘制控件及其各项前后发送一个通知,从而让编程人员更好地控制该过程。
在所有情况下,单一的 NM_CUSTOMDRAW 处理程序在每个绘制阶段都进行调用。然而,谨记:自定义绘制允许您在自己的绘制中合并默认的控件绘制,您需要指定您将处理哪个绘制阶段。这通过设置 NM_CUSTOMDRAW 处理程序的第二个参数 (pResult) 完成。事实上,如果您从未设置该值,则用初始阶段的 CDDS_PREPAINT 调用函数后,您的函数将不再被调用!
从技术上讲,只有两个阶段指定需要的绘制阶段(CDDS_PREPAINT 和 CDDS_ITEMPREPAINT),它们影响发送通知消息的内容。然而,通常只在处理程序的最后指定代码将处理的绘制阶段。表 2 列出用于指定所需绘制阶段(代码关注的)的值。
表 2:自定义绘制返回标志
自定义绘制返回标志 含义 CDRF_DEFAULT 指示控件自行绘制。该值为默认值,不应该将它与其他值组合在一起。 CDRF_SKIPDEFAULT 用于指定控件根本不进行任何绘制。 CDRF_NEWFONT 当代码更改绘制项/子项的字体时使用。 CDRF_NOTIFYPOSTPAINT 使通知信息在控件或每个项/子项绘制后发送。 CDRF_NOTIFYITEMDRAW 指出项(或子项)将进行绘制。注意,它下面的值与 CDRF_NOTIFYSUBITEMDRAW 相同。 CDRF_NOTIFYSUBITEMDRAW 指出子项(或项)将进行绘制。注意,它下面的值与 CDRF_NOTIFYITEMDRAW 相同。 CDRF_NOTIFYPOSTERASE 当删除控件后需要通知代码时使用。
以下为一个示例,其中的代码指定,当绘制控件的项 (CDRF_NOTIFYITEMDRAW) 及子项 (CDRF_NOTIFYPOSTPAINT),以及绘制完成时,应该调用 NM_CUSTOMDRAW 处理程序。
void CListCtrlWithCustomDraw::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR);
...
*pResult = 0; // Initialize value
*pResult |= CDRF_NOTIFYITEMDRAW;
*pResult |= CDRF_NOTIFYSUBITEMDRAW;
*pResult |= CDRF_NOTIFYPOSTPAINT;
}
筛选指定的绘制阶段
一旦指定要关注的阶段后,您需要处理这些阶段。因为绘制过程的每个阶段只有一个消息要发送,惯例是执行一个 switch 语句以决定准确的绘制阶段。不同的绘制阶段由以下标志定义:
CDDS_PREPAINT
CDDS_ITEM
CDDS_ITEMPREPAINT
CDDS_ITEMPOSTPAINT
CDDS_ITEMPREERASE
CDDS_ITEMPOSTERASE
CDDS_SUBITEM
CDDS_POSTPAINT
CDDS_PREERASE
CDDS_POSTERASE
对于一个 CListCtrl 派生的类,有一个 NM_CUSTOMDRAW 处理程序的示例,其中您可以发现,代码决定当前绘制阶段的方式:
void CMyCustomDrawControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR);
switch(pNMCD->dwDrawStage)
{
case CDDS_PREPAINT:
...
break;
case CDDS_ITEMPREPAINT:
...
break;
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
...
break;
...
}
*pResult = 0;
}
注意,为了决定子项(例如,列表视图控件)绘制的阶段,您必需使用按位 or 操作符,它有两个值:其中一个为 CDDS_ITEMPREPAINT 或者 CDDS_ITEMPOSTPAINT,另一个为 CDDS_SUBITEM。
要说明它,我们假定您想在绘制列表视图项之前进行一些处理。将编写 switch 语句来处理 CDDS_ITEMPREPAINT。
case CDDS_ITEMPREPAINT:
...
break;
然而,如果是您所关注子项的预绘制阶段,则将如下操作:
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
...
break;
- Visual C++2005中开发自定义绘图控件之二
- Visual C++2005中开发自定义绘图控件之三
- Visual C++2005中开发自定义绘图控件
- Visual C++2005中开发自定义绘图控件2.3
- Visual C++2005中开发自定义绘图控件之一
- Visual C++2005中开发自定义绘图控件
- Visual C++2005中开发自定义绘图控件
- 在 Visual C++ 中开发自定义的绘图控件(二)
- Visual Studio 2005:在 Visual C++ 中开发自定义的绘图控件
- Visual Studio 2005:在 Visual C++ 中开发自定义的绘图控件
- Visual Studio 2005:在 Visual C++ 中开发自定义的绘图控件
- 转自MSDN: Visual Studio 2005:在 Visual C++ 中开发自定义的绘图控件
- 在Visual C++ 中开发自定义的绘图控件
- 在 Visual C++ 中开发自定义的绘图控件
- 在 Visual C++ 中开发自定义的绘图控件 NM_CUSTOMDRAW
- 在 Visual C++ 中开发自定义的绘图控件(一)
- VC++2005中开发自定义绘图控件
- VC++2005中开发自定义绘图控件
- 分别基于虚函数和模版方式实现的多态
- MySQL中的时间日期函数
- Visual C++2005中开发自定义绘图控件之一
- VM(VMware Workstation)对开发的帮助
- SDE的连接方法
- Visual C++2005中开发自定义绘图控件之二
- 打开Windows组策略失败的原因分析
- Visual C++2005中开发自定义绘图控件之三
- 可口可乐公司的招聘题目——如果是你,你会怎么做?
- __atribute__使用:关于_attribute__ ((used,__section__(".xxxx")))的理解
- 一位软件设计师的6年总结
- COM ATL IDispatchEx InvokeEx 钩子
- how to use ocx control in console app.
- 四大关键词 解读08年韩国游戏企业