關於自定義繪製
本節包含自定義繪製功能的一般資訊,並提供應用程式如何支援自定義繪製的概念性概觀。 目前,下列控件支援自定義繪製功能:
- 標頭控件
- 清單檢視控件
- Rebar 控件
- 工具列控制項
- 工具提示控件
- 追蹤列控件
- 樹視圖控件
關於自定義繪製通知訊息
支援自定義繪製的所有常見控件都會在繪圖作業期間在特定點傳送 NM_CUSTOMDRAW 通知碼。 這些通知代碼描述套用至整個控件的繪圖作業,以及控件內專案特定的繪圖作業。 和許多通知代碼一樣,NM_CUSTOMDRAW通知會以WM_NOTIFY訊息的形式傳送。
自定義繪製通知的 lParam 參數會是 NMCUSTOMDRAW 結構的位址,或是包含 NMCUSTOMDRAW 結構做為其第一個成員的控件特定結構。 下表說明控件與其使用結構之間的關聯性。
結構 | 使用對象 |
---|---|
NMCUSTOMDRAW | Rebar、Trackbar 和標頭控件 |
NMLVCUSTOMDRAW | 清單檢視控件 |
NMTBCUSTOMDRAW | 工具列控制項 |
NMTTCUSTOMDRAW | 工具提示控件 |
NMTVCUSTOMDRAW | 樹視圖控件 |
小畫家 週期、繪圖階段和通知訊息
和所有 Windows 應用程式一樣,一般控件會根據從系統或其他應用程式收到的訊息定期繪製和清除自己。 控件繪製或清除本身的程序稱為 油漆迴圈。 支援自定義繪製 的控件會定期透過每個繪製週期傳送NM_CUSTOMDRAW 通知碼。 此通知程式代碼隨附 NMCUSTOMDRAW 結構,或包含 NMCUSTOMDRAW 結構做為其第一個成員的另一個結構。
NMCUSTOMDRAW 結構所包含的其中一個資訊是繪製週期的目前階段。 這稱為 繪製階段 ,並以結構 dwDrawStage 成員中的值表示。 控件會通知其父系四個基本繪製階段。 這些基本或全域繪製階段會以下列旗標值在 結構中表示(定義於 Commctrl.h 中)。
全域繪製階段值 | 描述 |
---|---|
CDDS_PREPAINT | 繪製周期開始之前。 |
CDDS_POSTPAINT | 完成繪製周期之後。 |
CDDS_PREERASE | 清除周期開始之前。 |
CDDS_POSTERASE | 清除週期完成之後。 |
上述每個值都可以與 CDDS_ITEM 旗標結合,以指定專案特定的繪製階段。 為了方便起見,Commctrl.h 包含下列專案特定值。
專案特定的繪製階段值 | 描述 |
---|---|
CDDS_ITEMPREPAINT | 繪製專案之前。 |
CDDS_ITEMPOSTPAINT | 繪製項目之後。 |
CDDS_ITEMPREERASE | 清除專案之前。 |
CDDS_ITEMPOSTERASE | 清除項目之後。 |
CDDS_SUBITEM | 通用控件 4.71 版 。 如果繪製子專案,則與CDDS_ITEMPREPAINT或CDDS_ITEMPOSTPAINT結合的旗標。 只有在從CDDS_PREPAINT傳回CDRF_NOTIFYITEMDRAW時,才會設定此設定。 |
您的應用程式必須處理 NM_CUSTOMDRAW 通知程式代碼,然後傳回特定值,告知控件其必須執行的動作。 如需這些傳回值的詳細資訊,請參閱下列各節。
利用自定義繪製服務
利用自定義繪製功能的關鍵在於回應 控件所傳送的NM_CUSTOMDRAW 通知碼。 您的應用程式為了回應這些通知而傳送的傳回值會決定該繪製週期的控件行為。
本節包含應用程式 如何使用NM_CUSTOMDRAW 通知傳回值來判斷控件的行為的相關信息。
詳細資料分成下列主題:
回應預付通知
在每個繪製週期的開頭,控件會傳送NM_CUSTOMDRAW通知碼,指定隨附NM_CUSTOMDRAW 結構之 dwDrawStage 成員中的CDDS_PREPAINT值。 您的應用程式傳回此第一個通知的值會決定控件針對該繪製週期其餘部分傳送後續自定義繪製通知的方式和時間。 您的應用程式可以傳回下列旗標的組合,以回應第一個通知。
傳回值 | 影響 |
---|---|
CDRF_DODEFAULT | 控件會自行繪製。 它不會傳送此油漆週期的其他 NM_CUSTOMDRAW 通知。 這個旗標不能與任何其他旗標搭配使用。 |
CDRF_DOERASE | 控件只會繪製背景。 |
CDRF_NEWFONT | 您的應用程式為專案指定了新的字型;控件會使用新的字型。 如需變更字型的詳細資訊,請參閱 變更字型和色彩。 當 dwDrawStage 等於 CDDS_ITEMPREPAINT 時,就會發生這種情況。 |
CDRF_NOTIFYITEMDRAW | 控件會通知父代任何專案特定的繪圖作業。 它會在繪製專案之前和之後傳送NM_CUSTOMDRAW通知碼。當 dwDrawStage 等於 CDDS_PREPAINT 時,就會發生這種情況。 |
CDRF_NOTIFYPOSTERASE | 控件會在清除項目之後通知父代。 當 dwDrawStage 等於 CDDS_PREPAINT 時,就會發生這種情況。 |
CDRF_NOTIFYPOSTPAINT | 當整個控件的繪製週期完成時,控件會傳送 NM_CUSTOMDRAW 通知。 當 dwDrawStage 等於 CDDS_PREPAINT 時,就會發生這種情況。 |
CDRF_NOTIFYSUBITEMDRAW | 4.71 版。 您的應用程式會收到NM_CUSTOMDRAW通知,dwDrawStage 設定為 CDDS_ITEMPREPAINT |在繪製每個清單檢視子專案之前CDDS_SUBITEM。 然後,您可以分別指定每個子專案的字型和色彩,或傳回默認處理CDRF_DODEFAULT。 當 dwDrawStage 等於 CDDS_ITEMPREPAINT 時,就會發生這種情況。 |
CDRF_SKIPDEFAULT | 您的應用程式會手動繪製專案。 控件不會繪製專案。 當 dwDrawStage 等於 CDDS_ITEMPREPAINT 時,就會發生這種情況。 |
CDRF_SKIPPOSTPAINT | 控制件不會在項目周圍繪製焦點矩形。 |
要求專案特定通知
如果您的應用程式將 CDRF_NOTIFYITEMDRAW 傳回初始預付自定義繪製通知,控件將會針對在繪製週期期間繪製的每個專案傳送通知。 這些專案特定的通知將會在隨附 NMCUSTOMDRAW 結構的 dwDrawStage 成員中具有CDDS_ITEMPREPAINT值。 您可以藉由將CDRF_NOTIFYPOSTPAINT傳回給這些專案特定的通知,要求控件在完成繪製專案時傳送另一個通知。 否則,傳回 CDRF_DODEFAULT ,而且控件在開始繪製下一個專案之前,不會通知父視窗。
自行繪製專案
如果您的應用程式繪製整個專案,請傳回 CDRF_SKIPDEFAULT。 這可讓控件略過不需要繪製的專案,進而降低系統負荷。 請記住,傳回此值表示控件不會繪製專案的任何部分。
變更字型和色彩
您的應用程式可以使用自定義繪製來變更專案的字型。 只要選取您想要的 HFONT 到與自訂繪製通知相關聯之 NMCUSTOMDRAW 結構的 hdc 成員所指定的裝置內容即可。 由於您選取的字型可能與預設字型不同,因此請務必 在通知訊息的傳回值中包含CDRF_NEWFONT 位。 如需使用此功能的詳細資訊,請參閱使用自定義繪製中的範例程序代碼。 應用程式指定的字型,用於在未選取該專案時顯示該專案。 自定義繪製不允許您變更所選取的字型屬性。
若要變更所有支援自定義繪製的控件的文字色彩,除了清單檢視和樹視圖之外,只要使用SetTextColor和 SetBkColor 函式,在自定義繪製通知結構中提供的裝置內容中設定所需的文字和背景色彩。 若要修改清單檢視或樹視圖中的文字色彩,您必須將所需的色彩值放在 NMLVCUSTOMDRAW 或 NMTVCUSTOMDRAW 結構的 clrText 和 clrTextBk 成員中。
注意
在 通用控件 6.0 版之前,工具列會忽略 CDRF_NEWFONT 旗標。 6.0 版支援 CDRF_NEWFONT 旗標,您可以使用它來選取工具列的不同字型。 不過,當可視化樣式為使用中時,您無法變更工具列的色彩。 若要在 6.0 版中變更工具列的色彩,您必須先呼叫 SetWindowTheme 並指定沒有視覺樣式來停用視覺樣式:
SetWindowTheme (hwnd, "", "");
使用清單檢視和樹視圖控件的自訂繪製
最常見的控件基本上可以以相同的方式處理。 不過,清單檢視和樹視圖控件有一些需要自定義繪製不同方法的功能。
對於 5.0 版,如果您傳回 CDRF_NEWFONT來變更字型,這兩個控件可能會顯示裁剪的文字。 這是與舊版通用控件回溯相容性的必要行為。 如果您想要變更清單檢視或樹視圖控件的字型,如果在將任何專案新增至控件之前,先傳送 wParam 值設定為 5 的CCM_SETVERSION訊息,就會取得更好的結果。 如需使用自定義繪製的樹視圖控件範例,請參閱知識庫文章範例:CustDTv 說明 TreeView 中的自定義繪製(Q248496)。
使用清單檢視控件的自定義繪製
由於清單檢視控制項具有子專案和多個顯示模式,因此您必須處理 NM_CUSTOMDRAW 通知與其他通用控制件稍有不同。
針對報表模式,請使用下列程式。
- 第一個NM_CUSTOMDRAW通知會讓相關聯 NMCUSTOMDRAW 結構的 dwDrawStage 成員設定為 CDDS_PREPAINT。 傳回 CDRF_NOTIFYITEMDRAW。
- 您接著會收到NM_CUSTOMDRAW通知,並將 dwDrawStage 設定為 CDDS_ITEMPREPAINT。 如果您指定新的字型或色彩並傳回 CDRF_NEWFONT,則會變更專案的所有子專案。 如果您想要分別處理每個子專案,請傳回 CDRF_NOTIFYSUBITEMDRAW。
- 如果您在上一個步驟中傳回CDRF_NOTIFYSUBITEMDRAW,則會收到每個子專案的NM_CUSTOMDRAW通知,並將 dwDrawStage 設定為 CDDS_SUBITEM |CDDS_ITEMPREPAINT。 若要變更該子專案的字型或色彩,請指定新的字型或色彩,並傳回 CDRF_NEWFONT。
針對大型圖示、小型圖示和清單模式,請使用下列程式。
- 第一個NM_CUSTOMDRAW通知會讓相關聯 NMCUSTOMDRAW 結構的 dwDrawStage 成員設定為 CDDS_PREPAINT。 傳回 CDRF_NOTIFYITEMDRAW。
- 您接著會收到NM_CUSTOMDRAW通知,並將 dwDrawStage 設定為 CDDS_ITEMPREPAINT。 您可以指定新的字型和色彩並傳 回CDRF_NEWFONT,來變更專案的字型或色彩。 由於這些模式沒有子專案,因此您不會收到任何其他NM_CUSTOMDRAW通知。
如需清單檢視 NM_CUSTOMDRAW 通知處理程式的範例,請參閱 使用自定義繪製。
相關主題