注意,为了决定子项(例如,列表视图控件)绘制的阶段,您必需使用按位 or 操作符,它有两个值:其中一个为 CDDS_ITEMPREPAINT 或者 CDDS_ITEMPOSTPAINT,另一个为 CDDS_SUBITEM。
要说明它,我们假定您想在绘制列表视图项之前进行一些处理。将编写 switch 语句来处理 CDDS_ITEMPREPAINT。
case CDDS_ITEMPREPAINT:break;
然而,如果是您所关注子项的预绘制阶段,则将如下操作:
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:break;返回页首
如前面提到的,您可以完全控制控件及其项的绘制,或者仅执行一小部分特定于应用程序的绘制,并让控件继续进行。本文的焦点更多地偏重于控件绘制技术而非高级的绘制技术,我们将演练一个简单的示例,其中列表视图控件是一个自定义的绘制,因此项的文本将在创建拼接外观的交替单元中显示为不同的颜色。
• | 创建一个基于 Visual C++ 2005 对话框的项目,名为 ListCtrlColor。 |
• | 从 Class View 中选择 Project 菜单选项,并单击 Add Class 调用 Add Class 对话框。 |
• | 从分类列表中选择 MFC,然后从模板列表中选择 MFC Class。 |
• | 单击 Add 按钮,调用 MFC Class Wizard 对话框。 |
• | 对于 Class name,键入值 CListCtrlWithCustomDraw 并选择 CListCtrl 的 Base class。 |
• | 单击 Finish 按钮,生成类的标头和执行文件。 |
• | 对于 Class View,右键单击 CListCtrlWithCustomDraw 类,并选择 Properties 上下文菜单选项。 |
• | 显示 Properties 窗口时,单击顶部的 Messages 按钮,显示一个两列的消息列表,您可以为其实现处理程序。 |
• | 在消息列表中单击 NM_CUSTOMDRAW 项,然后下拉第二列的组合框箭头,并选择值 OnNMCustomdraw。 |
• | 现在,处理绘制代码。这里,我们只简单处理项和子项预绘制阶段,指定基于当前行(项)和列(子项)的文本和背景色。要进行此操作,按如下所示修改 OnNMCustomdraw 函数: void CListCtrlWithCustomDraw::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult){ LPNMLVCUSTOMDRAW lpLVCustomDraw = reinterpret_cast(pNMHDR); switch(lpLVCustomDraw->nmcd.dwDrawStage) { case CDDS_ITEMPREPAINT: case CDDS_ITEMPREPAINT | CDDS_SUBITEM: if (0 == ((lpLVCustomDraw->nmcd.dwItemSpec + lpLVCustomDraw->iSubItem) % 2)) { lpLVCustomDraw->clrText = RGB(255,255,255); // white text lpLVCustomDraw->clrTextBk = RGB(0,0,0); // black background } else { lpLVCustomDraw->clrText = CLR_DEFAULT; lpLVCustomDraw->clrTextBk = CLR_DEFAULT; } break; default: break; } *pResult = 0; *pResult |= CDRF_NOTIFYPOSTPAINT; *pResult |= CDRF_NOTIFYITEMDRAW; *pResult |= CDRF_NOTIFYSUBITEMDRAW;} |
现在,我们来测试新控件。要进行此操作,您只需使用 CListCtrlWithCustomDraw 类将列表视图控件放在对话框中,并对其进行子类派生。下面是完成该操作的步骤。
• | 在 Resource 视图中,打开应用程序的主对话框 (IDD_LISTCTRLCOLOR_DIALOG)。 |
• | 从 Toolbox 中,将一个 List Control 拖放到该对话框。 |
• | 右键单击列表控件,并选择 Properties 上下文菜单选项。 |
• | 将 View 属性设置为 Report。 |
• | 右键单击控件,并选择 Add Variable 上下文菜单选项。 |
• | 出现 Add Member Variable Wizard 对话框时,指定 m_lstBooks 的 Variable name,并单击 Finish 按钮。 |
• | 这时,您就有了一个 CListCtrl 派生类 (m_lstBooks),它将对话框上的列表视图控件进行子类派生。然而,m_lstBooks 需要从最新创建的 CListCtrlWithCustomDraw 派生,以便于调用您的绘制代码。因此,打开对话框的标题文件 (ListCtrlColorDlg.h),将 m_lstBooks 更改为 CListCtrlWithCustomDraw 类型。 |
• | 在 CListCtrlColorDlg 类开始之前,添加以下指令。 #include "ListCtrlWithCustomDraw.h" |
• | 将下面的代码添加到对话框的 OnInitDialog 成员函数,这样我们就能够看到一些列表视图行。 // Insert the columnsm_lstBooks.InsertColumn(0, _T("Author"));m_lstBooks.InsertColumn(1, _T("Book"));// Define the datastatic struct { TCHAR m_szAuthor[50]; TCHAR m_szTitle[100];} BOOK_INFO = {_T("Tom Archer"), _T("Visual C++.NET Bible"),_T("Tom Archer"), _T("Extending MFC with the .NET Framework"),_T("Brian Johnson"), _T("XBox 360 For Dummies")};// Insert the dataint idx;for (int i = 0; i < sizeof BOOK_INFO / sizeof BOOK_INFO[0]; i++){ idx = m_lstBooks.InsertItem(i, BOOK_INFO[i].m_szAuthor); m_lstBooks.SetItemText(i, 1, BOOK_INFO[i].m_szTitle);} |
• | 现在,建立并运行应用程序。图 1 为应用程序外观的一个示例。 图 1. 自定义绘制示例应用程序 |