Posted on 2010-12-03 01:24
Tinpont 閱讀(1539)
評論(0) 編輯 收藏 引用 所屬分類:
C++/MFC
本文的焦點更多地偏重于控件繪制技術而非高級的繪制技術,我們將演練一個簡單的示例,其中列表視圖控件是一個自定義的繪制,因此項的文本將在創建拼接外觀的交替單元中顯示為不同的顏色。
創建一個基于 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 columns
m_lstBooks.InsertColumn(0, _T("Author"));
m_lstBooks.InsertColumn(1, _T("Book"));

// Define the data
static 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 data
int 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. 自定義繪制示例應用程序
小結
當 Windows 首次作為“下一代”操作系統引入到應用程序開發之中時,它作為新圖形用戶界面的一個主要論據就是其一致性。該論據的要點所在是其具有一個通用的外觀:統一的菜單項、通用控件等。這一通用性的感覺可能會一直延續,直到有第二家公司想設計其自己的應用程序。簡單說,提供外觀與其他應用程序雷同的應用程序,任何公司都不會逃離這一怪圈。
要建立一個唯一的且讓人過目難忘的用戶界面,其中一種方式是為應用程序設計并開發自定義的控件。希望本文能對您有所幫助,現在,您了解到一種非常強大的技術,它使您的應用程序能從眾多競爭對手的應用程序中脫穎而出。