VisualC++2005中開發(fā)自定義繪圖控件

字號(hào):

在您決定開發(fā) Windows 提供的常規(guī)免費(fèi)自定義控件范圍之外的控件之后,您必需確定自己的控件將有多少獨(dú)到之處 — 在功能和外觀兩方面。例如,我們假定您正在創(chuàng)建一個(gè)類似于計(jì)速表的控件。由于公共控件庫 (ComCtrl32.dll) 中沒有類似的控件,您完全需要自己進(jìn)行以下操作:編寫所有控件功能需要的代碼,進(jìn)行繪制,默認(rèn)終端用戶的交互,以及控件與其父窗口之間需要的任意消息處理。
    另一方面,還包括一些您只想調(diào)整公共控件功能的情況。例如,我們假定您想創(chuàng)建一個(gè)屏蔽編輯控件,它只允許接受指定的字符。如果使用 MFC,通常涉及從 MFC 提供的類派生一個(gè)類,該類封裝了一個(gè)公共控件(在屏蔽編輯控件中,通常為 CEdit),重寫必需的虛函數(shù)(或處理指定的消息),然后加入自定義的代碼。
    本文討論的重點(diǎn)介于兩者之間 — 公共控件賦予您想要的大部分功能,但控件的外觀并不是您想要的。例如,列表視圖控件提供在許多視圖風(fēng)格中顯示數(shù)據(jù)列表的方式 — 小圖標(biāo)、大圖標(biāo)、列表和詳細(xì)列表(報(bào)告)。然而,如果您想要一個(gè)網(wǎng)格控件,那結(jié)果怎樣呢?盡管公共控件庫里沒有特別包含網(wǎng)格,但是列表視圖控件與它較為接近,它以行和列顯示數(shù)據(jù),并有一個(gè)相關(guān)的標(biāo)頭控件。因此,許多人以一個(gè)標(biāo)準(zhǔn)的列表視圖控件為起點(diǎn)創(chuàng)建自己的網(wǎng)格控件,然后重寫該控件及其子項(xiàng)的呈現(xiàn)方式或繪制方式。
    主宰繪圖操作
    即使“只”進(jìn)行繪制,您仍然有至少四種選項(xiàng)可用,它們都具有鮮明的優(yōu)缺點(diǎn):
    ·處理 WM_PAINT
    ·所有者繪制
    ·自定義繪制
    ·處理 WM_CTLCOLOR
    處理 WM_PAINT
    最極端的選擇是執(zhí)行一個(gè) WM_PAINT 處理程序,并且自己完成所有的繪制。這意味著,您的代碼將需要進(jìn)行一些與呈現(xiàn)控件相關(guān)的瑣事 — 創(chuàng)建適當(dāng)?shù)脑O(shè)備上下文(一個(gè)或多個(gè)),決定控件的大小和位置,繪制控件等。在繪制過程中,很少需要這種級(jí)別的控件。
    所有者繪制
    控制控件繪制的另一種方法是利用所有者繪制。事實(shí)上,您也許聽開發(fā)人員提到過所有者繪制控件,因?yàn)樗怯糜陂_發(fā)自定義控件最普通的技術(shù)。該技術(shù)普遍使用的主要原因在于,Windows 可為您提供很多幫助。在呈現(xiàn)控件的那一刻,Windows 就已經(jīng)創(chuàng)建并填寫了設(shè)備上下文,決定了控件的大小和位置,并且向您傳遞信息以使您了解此刻繪制的需求。對(duì)于列表控件(例如,列表框和列表視圖),Windows 將為列表中的每一項(xiàng)調(diào)用繪制代碼,這意味著您只需繪制這些項(xiàng),而無需考慮控件的其他方面。注意,所有者繪制可用于大多數(shù)控件。然而,它不能用于編輯控件;并且考慮到列表控件,它只能用于報(bào)表視圖樣式。
    自定義繪制
    對(duì)于繪制自己的控件而言,這可能是最少為人所知的技術(shù)。事實(shí)上,許多技術(shù)能力較高的開發(fā)人員也混淆了術(shù)語所有者繪制 (owner-draw) 和自定義繪制 (custom-draw)。關(guān)于自定義控件,首先需要了解,它僅針對(duì)于指定的公共控件:標(biāo)頭、列表視圖、rebar、工具欄、工具提示、跟蹤條和樹視圖。此外,盡管所有者繪制只允許繪制報(bào)告視圖風(fēng)格的列表視圖控件,而自定義繪制則使您能夠處理列表視圖控件所有視圖風(fēng)格的繪制。使用自定義繪制的另一個(gè)明顯優(yōu)勢(shì)是,您可以對(duì)希望繪制的內(nèi)容進(jìn)行嚴(yán)格挑選。實(shí)現(xiàn)方式是,在控件繪制的每個(gè)階段由 Windows 向代碼發(fā)送一個(gè)消息。這樣,您可以決定在每個(gè)階段是自己進(jìn)行所有的繪制工作,增加默認(rèn)的繪制,還是允許 Windows 為該階段執(zhí)行所有的繪制。(鑒于自定義繪制是本文的一個(gè)主題,因此您很快會(huì)看到它的工作方式。)
    處理 WM_CTLCOLOR
    這可能是幫助決定如何呈現(xiàn)控件最簡單的方式。正如消息名所指,當(dāng)要繪制一個(gè)控件,并且它能讓您的代碼決定要使用的畫筆時(shí),發(fā)送 WM_CTLCOLOR 消息。通常情況下,如果您只想更改控件的顏色,并且不提供除控件本身之外的更多功能,則使用該技術(shù)。此外,對(duì)于由 Internet Explorer 引入的公共控件(列表視圖、樹視圖、rebar 等),不發(fā)送該消息,并且它只與標(biāo)準(zhǔn)控件(編輯、列表框等)協(xié)同使用。
    實(shí)現(xiàn)自定義繪制的三步曲
    既然您已經(jīng)了解了繪制控件可用的各種選項(xiàng)(包括使用自定義繪制的好處),那么,讓我們來看看實(shí)現(xiàn)一個(gè)自定義繪制控件需要的三個(gè)主要步驟。
    ·執(zhí)行一個(gè) NM_CUSTOMDRAW 消息處理程序。
    ·指定處理所需的繪制階段。
    ·篩選特定的繪制階段(在這些階段中,您需要加入自己的特定于控件的繪制代碼)。