Visual C++2005中開發自訂繪圖控制項

來源:互聯網
上載者:User
本文原始碼下載:CustomDraw.exe。

  在您決定開發 Windows 提供的常規免費自訂控制項範圍之外的控制項之後,您必需確定自己的控制項將有多少獨到之處 — 在功能和外觀兩方面。例如,我們假定您正在建立一個類似於計速表的控制項。由於公用控制項陳列庫 (ComCtrl32.dll) 中沒有類似的控制項,您完全需要自己進行以下操作:編寫所有控制項功能需要的代碼,進行繪製,預設終端使用者的互動,以及控制項與其父視窗之間需要的任意訊息處理。

  另一方面,還包括一些您只想調整公用控制項功能的情況。例如,我們假定您想建立一個屏蔽編輯控制項,它只允許接受指定的字元。如果使用 MFC,通常涉及從 MFC 提供的類派生一個類,該類封裝了一個公用控制項(在屏蔽編輯控制項中,通常為 CEdit),重寫必需的虛函數(或處理指定的訊息),然後加入自訂的代碼。

  本文討論的重點介於兩者之間 — 公用控制項賦予您想要的大部分功能,但控制項的外觀並不是您想要的。例如,列表視圖控制項提供在許多視圖風格中顯示資料列表的方式 — 小表徵圖、大表徵圖、列表和詳細列表(報告)。然而,如果您想要一個網格控制項,那結果怎樣呢?儘管公用控制項陳列庫裡沒有特別包含網格,但是列表視圖控制項與它較為接近,它以行和列顯示資料,並有一個相關的標題控制項。因此,許多人以一個標準的列表視圖控制項為起點建立自己的網格控制項,然後重寫該控制項及其子項的呈現方式或繪製方式。

  主宰繪圖操作

  即使“只”進行繪製,您仍然有至少四種選項可用,它們都具有鮮明的優缺點:

  ·處理 WM_PAINT

  ·所有者繪製

  ·自訂繪製

  ·處理 WM_CTLCOLOR

  處理 WM_PAINT

  最極端的選擇是執行一個 WM_PAINT 處理常式,並且自己完成所有的繪製。這意味著,您的代碼將需要進行一些與呈現控制項相關的瑣事 — 建立適當的裝置上下文(一個或多個),決定控制項的大小和位置,繪製控制項等。在繪製過程中,很少需要這種層級的控制項。

  所有者繪製

  控制控制項繪製的另一種方法是利用所有者繪製。事實上,您也許聽開發人員提到過所有者繪製控制項,因為它是用於開發自訂控制項最普通的技術。該技術普遍使用的主要原因在於,Windows 可為您提供很多協助。在呈現控制項的那一刻,Windows 就已經建立並填寫了裝置上下文,決定了控制項的大小和位置,並且向您傳遞資訊以使您瞭解此刻繪製的需求。對於清單控制項(例如,列表框和列表視圖),Windows 將為列表中的每一項調用繪製代碼,這意味著您只需繪製這些項,而無需考慮控制項的其他方面。注意,所有者繪製可用於大多數控制項。然而,它不能用於編輯控制項;並且考慮到清單控制項,它只能用於報表視圖樣式。

  自訂繪製

  對於繪製自己的控制項而言,這可能是最少為人所知的技術。事實上,許多技術能力較高的開發人員也混淆了術語所有者繪製 (owner-draw) 和自訂繪製 (custom-draw)。關於自訂控制項,首先需要瞭解,它僅針對於指定的公用控制項:標題、列表視圖、rebar、工具列、工具提示、跟蹤條和樹視圖。此外,儘管所有者繪製只允許繪製報表檢視風格的列表視圖控制項,而自訂繪製則使您能夠處理列表視圖控制項所有視圖風格的繪製。使用自訂繪製的另一個明顯優勢是,您可以對希望繪製的內容進行嚴格挑選。實現方式是,在控制項繪製的每個階段由 Windows 向代碼發送一個訊息。這樣,您可以決定在每個階段是自己進行所有的繪製工作,增加預設的繪製,還是允許 Windows 為該階段執行所有的繪製。(鑒於自訂繪製是本文的一個主題,因此您很快會看到它的工作方式。)

  處理 WM_CTLCOLOR

  這可能是協助決定如何呈現控制項最簡單的方式。正如訊息名所指,當要繪製一個控制項,並且它能讓您的代碼決定要使用的畫筆時,發送 WM_CTLCOLOR 訊息。通常情況下,如果您只想更改控制項的顏色,並且不提供除控制項本身之外的更多功能,則使用該技術。此外,對於由 Internet Explorer 引入的公用控制項(列表視圖、樹視圖、rebar 等),不發送該訊息,並且它只與標準控制項(編輯、列表框等)協同使用。

  實現自訂繪製的三步曲

  既然您已經瞭解了繪製控制項可用的各種選項(包括使用自訂繪製的好處),那麼,讓我們來看看實現一個自訂繪製控制項需要的三個主要步驟。

  ·執行一個 NM_CUSTOMDRAW 訊息處理常式。

  ·指定處理所需的繪製階段。

  ·篩選特定的繪製階段(在這些階段中,您需要加入自己的特定於控制項的繪製代碼)。

  執行一個NM_CUSTOMDRAW 訊息處理常式

  當需要繪製一個公用控制項時,MFC 會將控制項的自訂繪製通知訊息(最初發送到控制項的父視窗)以 NM_CUSTOMDRAW 訊息的形式反饋給控制項。以下是一個 NM_CUSTOMDRAW 處理常式的樣本。

void CMyCustomDrawControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
 LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR);
 ...
}

  正如您所見,NM_CUSTOMDRAW 處理常式將一個指標傳遞給 NMHDR 類型的結構。然而,該值不足以用於象 NMHDR 這樣只包含三個成員(hwndFrom、idFrom 和 code)的結構。

  因此,您通常需要將該結構指標轉換為資訊量更大的結構 — LPNMCUSTOMDRAW。LPNMCUSTOMDRAW 指向 NMCUSTOMDRAW,它包含諸如 dwDrawStage、dwItemSpec 和 uItemState 這樣的成員 — 它們是決定當前繪製階段及確切繪製(例如,控制項本身、或控制項的一個項目或子項)所必需的。

  這裡值得注意的是,還可以將 NMHDR 指標指向特定於正在繪製控制項的類型的結構。表 1 顯示控制項的一個列表及其相關的自訂繪製結構類型名。

  表 1:控制項及其相關的自訂繪製結構

控制項 結構(在 commctrl.h 中定義)
Rebar、Trackbar、AuthTicket、My.Resources、My.Settings、My.User 和 My.WebServices。 NMCUSTOMDRAW
List-view NMLVCUSTOMDRAW
Toolbar NMTBCUSTOMDRAW
Tooltip NMTTCUSTOMDRAW
Tree-view NMTVCUSTOMDRAW

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.