wm_drawitem與drawitem()的討論
我在學習中經常遇到要重寫drawitem()的情況,但又有乙個wm_drawitem訊息,它們是什麼樣的關係呢。
如果我們要重寫乙個cbutton取名為cmybutton,我們可以重寫cmybutton的drawitem()函式來實現我們的
需求,但cmybutton::drawitem()是在什麼時候呼叫呢?它是在它的宿主類的ondrawitem()中被呼叫,
ondrawitem(int nidctl, lpdrawitemstruct lpdrawitemstruct )正是對wm_drawitem的相應函式。
宿主類可以根據nidctl來判定是哪個子控制項。其實我們可以在ondrawitem函式裡對子控制項進行繪製,但是有很多
的子控制項看起來不好,所以我們應該在子類的drawitem對子類繪製,例如cmybutton::drawitem。所以可以
這樣理解,ondrawitem是畫視窗中的子控制項的,因為它的入口引數lpdrawitemstruct帶入不同子控制項的相
關引數,而且,你得把字控制項設定成「自畫」型別,才會呼叫到ondrawitem。
當自繪按鈕(owner-draw button),下拉列表框(combo box),列表框(list box)視覺屬性,或者選單發生變化時,
框架為他們的owner呼叫ondrawitem(傳送wm_drawitem),在宿主類呼叫子類的drawitem(傳送wm_drawitem訊息)。
我們可以過載子類的drawitem可以繪製自己需要的控制項,不是所有設定成自畫型別的控制項都會呼叫父視窗的ondrawitem,
例如listbox的自畫,你就必須過載clistbox的drawitem方法和measureitem方法才可以,但象選單,按鈕等的自畫則會呼叫
ondrawitem。在sdk中,子類是不可能受到wm_drawitem,在mfc中可以,這是類的設計者設計的(反射),這的確不錯。
在學習中還有乙個訊息也是由宿主類被呼叫的,它就是wm_ctrcolor。這個訊息是在子控制項將要繪畫時,向宿主
類傳送,宿主類利用發射機制讓子類自己又乙個處理的機會。onctlcolor (cdc* pdc, cwnd* pwnd, uint nctlcolor)
pdc,pwnd都是於子類相關的,在這裡可以設定,前景顏色,背景顏色,畫刷型別,字型等等,但不能改變元素的介面框架,
這是drawitem 所能幹的。
如果同時有drawitem(子類),ondrawitem(宿主類),onctlcolor(宿主類),它們的呼叫順序是:
onctlcolor,ondrawitem,drawitem。
如果我們同時又相應的子類的wm_paint訊息,這也許onpaint在內部進行了一些處理,判斷是否自繪來決定是否向宿主類
傳送wm_drawitem,所以如果響應了wm_paint子類就不會向宿主類傳送wm_drawitem訊息,你要完成子類的全部繪
制工作,如果子類是乙個列表框,就很麻煩。這時呼叫順序是onctlcolor,onpaint。
在傳送乙個wm_paint訊息前,總會先傳送乙個wm_eraseback訊息,我們在這裡在乙個背景。
對於我們平時對控制項的繪製,上面介紹的差不多了,還有乙個cview的問題,也就是onpaint和ondraw的關係,
其實這個很簡單,cview::onpaint()的原始碼如下:
[cpp]view plain
copy
void
cview::onpaint()
從**中可以清楚的看出他們的關係。
MFC自繪按鈕
1.建立乙個基於對話方塊的程式 2.在這裡,我是將 確定 按鈕重繪,拉大 確定 按鈕 如下 修改為自繪 3.新增位 件id為iidb bitmap1 4.新增類cmybutton基類為cbutton 後面兩個函式是我自己新增的,其中drawitem函式在基類中為虛函式,我們在派生類中過載,負責按鈕的...
MFC自繪控制項
1.c 中drawitem 函式不被呼叫的問題 自繪乙個cmybutton的時候,在drawitem 中改變了button的顏色,但是在程式執行時,drawitem 函式並沒有被執行,原因在於按鈕的型別並不是bs ownerdraw,所以我們需要把它改為 所有者繪製 解決方法 可以過載乙個presu...
MFC之自繪控制項
在描繪mfc介面時,mfc自帶的控制項樣式是絕對不滿足介面的需求的。所以我們就要在mfc自帶控制項基礎上對控制項樣式進行重繪。在採用自繪前介面樣式 採用自繪後介面樣式 是不是自繪控制項後看起來正常了很多?自繪控制項的步驟 我們以做乙個關閉按鈕為例 先建立乙個mfc類繼承自cbutton。給這個類新增...