第一步:改變對話框的背景顏色
如何改變對話框的背景顏色這個問題常常出現(xiàn)在論壇上,可見大家對Windows默認的灰色對話框是多么不滿。MFC程序修改對話框的背景和文字顏色最簡單的方法就是調(diào)用SetDialogBkColor函數(shù),SetDialogBkColor是CWinApp類的成員函數(shù),以下是該函數(shù)的原型:
請注意,SetDialogBkColor函數(shù)并不是對Windows的某個API的封裝,他是MFC框架的一部分,所以不使用MFC的程序也就不能享受這種方便。這個函數(shù)的使用很簡單,在程序的CWinApp派生類的InitInstance函數(shù)中添加一行代碼就行了:
SetDialogBkColor也有局限的地方,那就是所有的控件文字顏色都一樣,不能針對不同的控件設(shè)置不同的文字顏色,還有就是不能設(shè)置Edit控件的顏色。不使用SetDialogBkColor函數(shù),直接編寫代碼控制對話框的背景顏色和控件文字顏色也不是很困難的事情,并且這種方法能夠提供更靈活的顏色設(shè)置方案,比如對不同類型的控件使用不同的文字顏色,使用高亮度的背景顏色突出某個控件等等,最重要的是能夠控制Edit控件的文字和背景顏色,下面就介紹這種方法。
首先是改變對話框的背景顏色。當(dāng)Windows系統(tǒng)需要重畫某個窗口客戶區(qū)的背景的時候,就會向該窗口發(fā)送WM_ERASEBKGND 消息,窗口的處理過程響應(yīng)這個消息重新畫窗口的背景,這個過程稱之為“自畫”。改變對話框的背景顏色的原理很簡單,就是響應(yīng)這個消息,用自定義的顏色填充對話框的客戶區(qū)背景,代替對話框窗口默認的背景填充動作。許多新手經(jīng)常問:“為什么在class wizard中找不到對話框的WM_ERASEBKGND消息,是不是對話框沒有這個消息”?其實對話框也是窗口,它也有WM_ERASEBKGND消息,只是MFC的class wizard使用的dialog過濾器將其過濾掉了(只是在message窗口的顯示中過濾了,并不是真的不響應(yīng)這個消息),為的是代碼編寫過程中突出對話框?qū)S械南⒑?a >控件事件。如圖.2 所示,只要在class wizard中的“class info” table標(biāo)簽下將消息過濾器改成Windows就可以在對話框的消息列表中看到WM_ERASEBKGND了。
下面的代碼寫在函數(shù)OnEraseBkgnd()中,就可以了。
CRect rcClient;
GetClientRect(&rcClient);
CBrush brush1(RGB(125,255,255));//創(chuàng)建紅色畫刷
pDC->FillRect(&rcClient,&brush1);
return TRUE;
第二步:改變控件的顏色
看起來不如剛才效果好,控件文字的顏色和背景色都沒有改變,這是因為我們還沒有處理WM_CTLCOLOR消息。WM_CTLCOLOR是Windows的控件向其父窗口發(fā)送最頻繁的通知消息之一,例如,許多控件發(fā)送WM_CTLCOLOR消息給父窗口,讓父窗口提供畫刷來畫自己的背景。MFC的窗口類對這個通知消息特殊對待,如果父窗口沒有處理這個通知消息,MFC的窗口類就根據(jù)WM_CTLCOLOR通知消息的來源將這個WM_CTLCOLOR消息發(fā)送回控件,讓控件自己處理,這就是所謂的“消息反射”,不僅是WM_CTLCOLOR,MFC對很多通知消息都做了反射,不過我們今天的例子沒有使用“消息反射”,我們在控件的父窗口,也就是對話框窗口處理這個通知消息。還有一點需要說明的是,WM_CTLCOLOR消息是16位的Windows平臺的消息,在32位的Windows平臺上取而代之的是一系列更明確的通知消息:
WM_CTLCOLORBTN 按鈕控件
WM_CTLCOLORDLG 對話框
WM_CTLCOLOREDIT 編輯控件
WM_CTLCOLORLISTBOX 列表框控件
WM_CTLCOLORSCROLLBAR 滾動條控件
WM_CTLCOLORSTATIC 靜態(tài)文本控件
MFC為了兼容性考慮,仍舊使用OnCtlColor響應(yīng)這些消息,但是通過參數(shù)nCtlColor來具體的區(qū)分他們。在這個函數(shù)中,我們可以通過改變pDC參數(shù)的屬性來改變控件的繪制,并返回相應(yīng)的畫刷句柄給控件,控件使用這個畫刷畫自己的背景。下面是我們修改后的OnCtlColor函數(shù):
圖.4 就是這段代碼的效果,在這里我們不分“青紅皂白”,向所有的控件返回我們自己的畫刷,看起來不錯,Edit控件的文字顏色也改了,但是好像多行Edit控件有了麻煩,看來需要對多行Edit控件特殊對待。
對于多行Edit控件特殊處理,如下所示,上面的問題解決了:
上面的代碼解決了IDC_EDIT_MULTI_LINE的問題,但是對每個多行Edit控件都要判斷ID,下面的方法可以一勞永逸地解決多行編輯控件的問題:
下面我們針對每個控件設(shè)置特殊的顏色,區(qū)分控件可以通過控件的ID,修改控件背景也很簡單,直接返回相應(yīng)的畫刷就可以了,下面就是顏色設(shè)置的完整代碼: