學習中經常遇到要重寫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()的原始碼如下:
void CView::OnPaint()
{
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
uj5u.com熱心網友回復:
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/33458.html
標籤:界面
上一篇:兼容性問題
下一篇:NM_CUSTOMDRAW
