1. 程式人生 > >控件的自繪

控件的自繪

reat true eat Owner 資源 bsp 全部 wm_paint box

常見的控件自繪的方法有父窗口的OnDrawItem()函數、子控件的OnDrawItem()函數、子控件的CtlColor()函數、子控件的OnPaint()函數,子控件的OnNMCustomdraw()函數等。自繪控件的話需要控件具有Owner Draw屬性,通過Create()創建控件的時候添加BS_OWNERDRAW屬性,或者在資源視圖中右擊控件->屬性->Owner Draw設為true。

1、父窗口的OnDrawItem()函數、子控件的OnDrawItem()函數

在MFC中子控件要繪制的時候框架就會向父窗口發送WM_DRAWITEM消息,而父窗口會在WM_DRAWITEM消息響應函數OnDrawItem()裏調用子控件的DrawItem()函數,所以我們既可以在父窗口的OnDrawItem()函數裏也可以在控件的OnDrawItem()函數裏進行 控件的繪制,不過一般都是選擇在子控件的OnDrawItem()函數裏繪制控件。

不是所有設置成自畫類型的控件都會調用父窗口的OnDrawItem,例如ListBox的自畫,你就必須重載CListBox的DrawItem方法和MeasureItem方法才可以,但按鈕、菜單等的自畫則會調用OnDrawItem。

2、子控件的CtlColor()函數

子控件開始繪制之前,還會向宿主類發送WM_CTLCOLOR消息,對應的消息響應函數為OnCtlColor,而宿主類收到WM_CTLCOLOR消息後會向子控件發送=WM_CTLCOLOR反射消息,讓子控件有一個自己處理繪制的機會(這就是MFC中的消息反射),子控件中=WM_CTLCOLOR消息響應函數為CtlColor()。我們一般在CtlColor中對子控件設置控件的前景顏色、背景顏色、畫刷類型、字體等但不能改變元素的界面框架,這是OnDrawItem或DrawItem所能幹的。

如果同時有DrawItem(子類),OnDrawItem(宿主類),CtlColor(子類),OnCtlColor (宿主類),則它們的調用順序是:OnCtlColor—>CtlColor—>OnDrawItem—>DrawItem。

3、子控件的OnPaint()函數

添加了子控件的WM_PAINT消息響應OnPaint,這時就不會向宿主類發送WM_DRAWITEM消息了,這時就需要在子類的OnPaint中完成子控件的全部繪制工作。如果子控件是一個List列表的話,這樣做就很麻煩,所以不建議在OnPaint()中進行控件的繪制。

還有就是在發送一個WM_PAINT消息前,總會先發送一個WM_ERASEBACK消息,我們可以在這裏添加一個背景圖片。

4、子控件的OnNMCustomdraw()函數

一些控件在繪制的時候會向宿主類發送NM_CUSTOMDRAW消息,NM_CUSTOMDRAW是通過WM_NOTIFY發送給父窗口的,父窗口收到後會向子控件發送反射消息=NM_CUSTOMDRAW,子控件的=NM_CUSTOMDRAW反射消息相應函數為OnNMCustomdraw()。

控件的自繪