MFC自繪控制項與介面美化4 人生幾何 新浪部落格

2021-10-10 11:56:03 字數 4003 閱讀 6370

3.3.6 nm_customdraw

大家也許熟悉wm_notify,控制項通過wm_notify向父視窗傳送訊息。在wm_notify訊息體中,部分控制項會傳送nm_customdraw告訴父視窗自己需要繪圖。 

可以反射nm_customdraw訊息,如: 

on_notify_reflect(nm_customdraw, oncustomdraw) 

afx_msg void oncustomdraw(nmhdr *pnmhdr, lresult *presult); 

引數: 

pnmhdr 說到底只是乙個指標,大多數情況下它指向乙個nmhdr結構物件,nmhdr結構如下: 

[cpp]view plain

copy

typedef

struct

tagnmhdr  

nmhdr;  

[cpp]view plain

copy

typedef

struct

tagnmhdr  

nmhdr;  

其中: 

hwndfrom 傳送方控制項的視窗控制代碼 

idfrom 傳送方控制項的id 

code 通知** 

對於某些控制項來說,pnmhdr則會解釋成其它內容更豐富的結構物件的指標,如:對於列表控制項來說,pnmhdr常常指向乙個nmcustomdraw物件,nmcustomdraw結構如下: 

[cpp]view plain

copy

typedef

struct

tagnmcustomdrawinfo  

nmcustomdraw, far * lpnmcustomdraw;  

[cpp]view plain

copy

typedef

struct

tagnmcustomdrawinfo  

nmcustomdraw, far * lpnmcustomdraw;  

hdr nmhdr物件 

dwdrawstage 當前繪製狀態,其取值如表7所示:

型別值 含義 

cdds_posterase 擦除迴圈結束 

cdds_postpaint 繪製迴圈結束 

cdds_preerase 準備開始擦除迴圈 

cdds_prepaint 準備開始繪製迴圈 

cdds_item 指定dwitemspec, uitemstate, litemlparam引數有效 

cdds_itemposterase 列表項擦除結束 

cdds_itempostpaint 列表項繪製結束 

cdds_itempreerase 準備開始列表項擦除 

cdds_itemprepaint 準備開始列表項繪製 

cdds_subitem 指定列表子項

表7 dwdrawstage的型別值與含義

hdc指定了繪製操作所使用的裝置環境。 

rc指定了將被繪製的矩形區域。 

dwitemspec 列表項的索引 

uitemstate 當前列表項的狀態,其取值如表8所示:

型別值 含義 

cdis_checked 標記狀態。 

cdis_default 預設狀態。 

cdis_disabled 禁止狀態。 

cdis_focus 焦點狀態。 

cdis_grayed 灰化狀態。 

cdis_selected 選中狀態。 

cdis_hotlight 熱點狀態。 

cdis_indeterminate 不定狀態。 

cdis_marked 標註狀態。

表8 uitemstate的型別值與含義

litemlparam 當前列表項的繫結資料 

presult 指向狀態值的指標,指定系統後續操作,依賴於dwdrawstage: 

當dwdrawstage為cdds_prepaint,presult含義如表9所示:

型別值 含義 

cdrf_dodefault 預設操作,即系統在列表項繪製迴圈過程不再傳送nm_customdraw。 

cdrf_notifyitemdraw 指定列表項繪製前後傳送訊息。 

cdrf_notifyposterase 列表項擦除結束時傳送訊息。 

cdrf_notifypostpaint 列表項繪製結束時傳送訊息。

表9 presult的型別值與含義(一) 

當dwdrawstage為cdds_itemprepaint,presult含義如表10所示:

型別值 含義 

cdrf_newfont 指定後續操作採用應用中指定的新字型。 

cdrf_notifysubitemdraw 列表子項繪製時傳送訊息。 

cdrf_skipdefault 系統不必再繪製該子項。

表10 presult的型別值與含義(二)

以下是乙個利用nm_customdraw訊息繪製出的多色列表框的例子: 

圖12 利用nm_customdraw訊息美化介面 

對應**如下: 

[cpp]view plain

copy

void

ccoollist::oncustomdraw(nmhdr *pnmhdr, 

lresult

*presult)  

else

if(cdds_itemprepaint == plvcd->nmcd.dwdrawstage)  

}  [cpp]view plain

copy

void

ccoollist::oncustomdraw(nmhdr *pnmhdr, 

lresult

*presult)  

else

if(cdds_itemprepaint == plvcd->nmcd.dwdrawstage)  

}  注意到上例採取了3.1所推薦的第2種實現方法,派生了乙個新類ccoollist。 

3.4 使用mfc類的虛函式機制

修改windows介面,除了從windows訊息機制下功夫,也可以從mfc類下功夫,這應該得益於類的虛函式機制。為了防止諸如「物件導向技術」等術語在此氾濫,以下僅舉一段**作為例子: 

[cpp]view plain

copy

void

cview::onpaint()    

[cpp]view plain

copy

void

cview::onpaint()    

這是mfc中viewcore.cpp中的源**,很多讀者總不明白ondraw()和onpaint()之間的關係,從以上的**中很容易看出,cview的wm_paint訊息響應函式onpaint()會自動呼叫cview::ondraw()。而作為開發者的使用者,可以通過簡單的ondraw()的過載實現對wm_paint的處理。所以說,對mfc類的虛函式的過載是對訊息機制的擴充套件。 

以下列出了與介面美化相關的虛函式,引數說明略去: 

cbutton::drawitem 

cchecklistbox::drawitem 

ccombobox::drawitem 

cheaderctrl::drawitem 

clistbox::drawitem 

cmenu::drawitem 

cstatusbar::drawitem 

cstatusbarctrl::drawitem 

ctabctrl::drawitem

virtual void drawitem( lpdrawitemstruct lpdrawitemstruct ); 

owner draw元素自繪函式 

很顯然,位圖選單都是通過這個drawitem畫出來的。限於篇幅,在此不再附以例程。

MFC自繪控制項與介面美化3 人生幾何 新浪部落格

生成的介面如下 圖7 利用wm ctlcolor訊息美化介面 3.3.4 wm drawitem onctlcolor只能修改元素的顏色,但不能修改元素的介面框架,wm drawitem則可以。當乙個具有owner draw風格的元素 包括按鈕 組合框 列表框和選單等 需要顯示外觀時,該元素會傳送一...

MFC自繪控制項

1.c 中drawitem 函式不被呼叫的問題 自繪乙個cmybutton的時候,在drawitem 中改變了button的顏色,但是在程式執行時,drawitem 函式並沒有被執行,原因在於按鈕的型別並不是bs ownerdraw,所以我們需要把它改為 所有者繪製 解決方法 可以過載乙個presu...

MFC之自繪控制項

在描繪mfc介面時,mfc自帶的控制項樣式是絕對不滿足介面的需求的。所以我們就要在mfc自帶控制項基礎上對控制項樣式進行重繪。在採用自繪前介面樣式 採用自繪後介面樣式 是不是自繪控制項後看起來正常了很多?自繪控制項的步驟 我們以做乙個關閉按鈕為例 先建立乙個mfc類繼承自cbutton。給這個類新增...