




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、創(chuàng)建有個(gè)性的對(duì)話框之MFC篇想使自己的軟件與眾不同就要給軟件加點(diǎn)“色”,一個(gè)顏色搭配協(xié)調(diào)的窗口要比windows千篇一律的灰底黑字更能吸引別人的眼球。設(shè)想如果html瀏覽器顯示的網(wǎng)頁(yè)都是白底黑字,還會(huì)有那么多的mm喜歡上網(wǎng)嗎?可能互聯(lián)網(wǎng)的人氣將下降一半。做個(gè)出色的界面對(duì)于老手來(lái)說(shuō)可能不在話下,但是對(duì)于新手來(lái)說(shuō)還是無(wú)從下手,使用BCGControlBar和Xtreme Toolkit是個(gè)很好的選擇,不過(guò)對(duì)于一個(gè)小程序使用這么大的庫(kù)未免有頭重腳輕的感覺(jué)。其實(shí)不使用這些龐然大物一樣可以做個(gè)很“色”的界面,本文就結(jié)合CSDN論壇上經(jīng)常被問(wèn)起的問(wèn)題,介紹幾個(gè)給對(duì)話框上色的方法。本文的方法都是針對(duì)MFC程
2、序的,其他方法請(qǐng)參看“創(chuàng)建有個(gè)性的對(duì)話框之ATL/WTL篇”。第一步:改變對(duì)話框的背景顏色如何改變對(duì)話框的背景顏色這個(gè)問(wèn)題常常出現(xiàn)在論壇上,可見(jiàn)大家對(duì)Windows默認(rèn)的灰色對(duì)話框是多么不滿。MFC程序修改對(duì)話框的背景和文字顏色最簡(jiǎn)單的方法就是調(diào)用SetDialogBkColor函數(shù),SetDialogBkColor是CWinApp類的成員函數(shù),以下是該函數(shù)的原型:void CWinApp:SetDialogBkColor(COLORREF clrCtlBk, COLORREF clrCtlText); 請(qǐng)注意,SetDialogBkColor函數(shù)并不是對(duì)Windows的某個(gè)API的封裝,他是
3、MFC框架的一部分,所以不使用MFC的程序也就不能享受這種方便。這個(gè)函數(shù)的使用很簡(jiǎn)單,在程序的CWinApp派生類的InitInstance函數(shù)中添加一行代碼就行了:SetDialogBkColor(RGB(188,197,230),RGB(13,125,188); 圖.1 就是運(yùn)行效果:圖.1 SetDialogBkColor效果圖使用SetDialogBkColor也有局限的地方,那就是所有的控件文字顏色都一樣,不能針對(duì)不同的控件設(shè)置不同的文字顏色,還有就是不能設(shè)置Edit控件的顏色。不使用SetDialogBkColor函數(shù),直接編寫代碼控制對(duì)話框的背景顏色和控件文字顏色也不是很困難的事
4、情,并且這種方法能夠提供更靈活的顏色設(shè)置方案,比如對(duì)不同類型的控件使用不同的文字顏色,使用高亮度的背景顏色突出某個(gè)控件等等,最重要的是能夠控制Edit控件的文字和背景顏色,下面就介紹這種方法。首先是改變對(duì)話框的背景顏色。當(dāng)Windows系統(tǒng)需要重畫某個(gè)窗口客戶區(qū)的背景的時(shí)候,就會(huì)向該窗口發(fā)送WM_ERASEBKGND 消息,窗口的處理過(guò)程響應(yīng)這個(gè)消息重新畫窗口的背景,這個(gè)過(guò)程稱之為“自畫”。改變對(duì)話框的背景顏色的原理很簡(jiǎn)單,就是響應(yīng)這個(gè)消息,用自定義的顏色填充對(duì)話框的客戶區(qū)背景,代替對(duì)話框窗口默認(rèn)的背景填充動(dòng)作。許多新手經(jīng)常問(wèn):“為什么在class wizard中找不到對(duì)話框的WM_ERASE
5、BKGND消息,是不是對(duì)話框沒(méi)有這個(gè)消息”?其實(shí)對(duì)話框也是窗口,它也有WM_ERASEBKGND消息,只是MFC的class wizard使用的dialog過(guò)濾器將其過(guò)濾掉了(只是在message窗口的顯示中過(guò)濾了,并不是真的不響應(yīng)這個(gè)消息),為的是代碼編寫過(guò)程中突出對(duì)話框?qū)S械南⒑涂丶录?。如圖.2 所示,只要在class wizard中的“class info” table標(biāo)簽下將消息過(guò)濾器改成Windows就可以在對(duì)話框的消息列表中看到WM_ERASEBKGND了。圖.2 修改消息過(guò)濾器現(xiàn)在通過(guò)class wizard添加WM_ERASEBKGND的消息響應(yīng)函數(shù),并如下所示修改這個(gè)函數(shù)
6、:BOOL CCustDlgDlg:OnEraseBkgnd(CDC* pDC) CRect rcClient;GetClientRect(&rcClient);pDC->FillRect(&rcClient,&m_brBkgnd);return TRUE;/return CDialog:OnEraseBkgnd(pDC);m_brBkgnd是個(gè)CBrush,在此之前已經(jīng)初始化過(guò)了,關(guān)鍵代碼是最后返回TRUE,而不是默認(rèn)的調(diào)用基類函數(shù),返回TRUE意在告訴Windows:“我已經(jīng)畫過(guò)背景了,你不要再畫了”?,F(xiàn)在來(lái)看看運(yùn)行的效果:圖.3 重畫背景的效果使用位圖作為對(duì)
7、話框的背景也不難,就是在整個(gè)客戶區(qū)畫一個(gè)位圖背景,第二步:改變控件的顏色看起來(lái)不如剛才效果好,控件文字的顏色和背景色都沒(méi)有改變,這是因?yàn)槲覀冞€沒(méi)有處理WM_CTLCOLOR消息。WM_CTLCOLOR是Windows的控件向其父窗口發(fā)送最頻繁的通知消息之一,例如,許多控件發(fā)送WM_CTLCOLOR消息給父窗口,讓父窗口提供畫刷來(lái)畫自己的背景。MFC的窗口類對(duì)這個(gè)通知消息特殊對(duì)待,如果父窗口沒(méi)有處理這個(gè)通知消息,MFC的窗口類就根據(jù)WM_CTLCOLOR通知消息的來(lái)源將這個(gè)WM_CTLCOLOR消息發(fā)送回控件,讓控件自己處理,這就是所謂的“消息反射”,不僅是WM_CTLCOLOR,MFC對(duì)很多通
8、知消息都做了反射,不過(guò)我們今天的例子沒(méi)有使用“消息反射”,我們?cè)诳丶母复翱?,也就是?duì)話框窗口處理這個(gè)通知消息。還有一點(diǎn)需要說(shuō)明的是,WM_CTLCOLOR消息是16位的Windows平臺(tái)的消息,在32位的Windows平臺(tái)上取而代之的是一系列更明確的通知消息:WM_CTLCOLORBTN 按鈕控件 WM_CTLCOLORDLG 對(duì)話框 WM_CTLCOLOREDIT 編輯控件 WM_CTLCOLORLISTBOX 列表框控件 WM_CTLCOLORSCROLLBAR 滾動(dòng)條控件WM_CTLCOLORSTATIC 靜態(tài)文本控件MFC為了兼容性考慮,仍舊使用OnCtlColor響應(yīng)這些消息,但是
9、通過(guò)參數(shù)nCtlColor來(lái)具體的區(qū)分他們。在這個(gè)函數(shù)中,我們可以通過(guò)改變pDC參數(shù)的屬性來(lái)改變控件的繪制,并返回相應(yīng)的畫刷句柄給控件,控件使用這個(gè)畫刷畫自己的背景。下面是我們修改后的OnCtlColor函數(shù):HBRUSH CCustDlgDlg:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) HBRUSH hbr = CDialog:OnCtlColor(pDC, pWnd, nCtlColor);pDC->SetTextColor(m_clrText);pDC->SetBkMode(TRANSPARENT);return (HB
10、RUSH)m_brBkgnd; /因?yàn)镃Brush類實(shí)現(xiàn)了HBRUSH類型轉(zhuǎn)換操作符/return hbr;圖.4 就是這段代碼的效果,在這里我們不分“青紅皂白”,向所有的控件返回我們自己的畫刷,看起來(lái)不錯(cuò),Edit控件的文字顏色也改了,但是好像多行Edit控件有了麻煩,看來(lái)需要對(duì)多行Edit控件特殊對(duì)待。圖.4 重載OnCtlColor之后的效果對(duì)于多行Edit控件特殊處理,如下所示,上面的問(wèn)題解決了:HBRUSH CCustDlgDlg:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) HBRUSH hbr = CDialog:OnCtlCo
11、lor(pDC, pWnd, nCtlColor);if(pWnd->GetDlgCtrlID() = IDC_EDIT_MULTI_LINE) /IDC_EDIT_MULTI_LINE是多行Edir控件的IDpDC->SetTextColor(m_clrText);return hbr;elsepDC->SetTextColor(m_clrText);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd;上面的代碼解決了IDC_EDIT_MULTI_LINE的問(wèn)題,但是對(duì)每個(gè)多行Edit控件都要判斷ID,下面的方法可
12、以一勞永逸地解決多行編輯控件的問(wèn)題:HBRUSH CCustDlgDlg:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) HBRUSH hbr = CDialog:OnCtlColor(pDC, pWnd, nCtlColor);TCHAR szClassName64;:GetClassName(pWnd->GetSafeHwnd(),szClassName,64);if(lstrcmpi(szClassName,_T("Edit") = 0) /是Edit 控件DWORD dwStyle = pWnd->Get
13、Style();if(dwStyle & ES_MULTILINE) = ES_MULTILINE) /多行edit控件pDC->SetTextColor(m_clrText);return hbr;elsepDC->SetTextColor(m_clrText);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd;else /不是編輯控件pDC->SetTextColor(m_clrText);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd;下
14、面我們針對(duì)每個(gè)控件設(shè)置特殊的顏色,區(qū)分控件可以通過(guò)控件的ID,修改控件背景也很簡(jiǎn)單,直接返回相應(yīng)的畫刷就可以了,下面就是顏色設(shè)置的完整代碼:HBRUSH CCustDlgDlg:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) HBRUSH hbr = CDialog:OnCtlColor(pDC, pWnd, nCtlColor);TCHAR szClassName64;:GetClassName(pWnd->GetSafeHwnd(),szClassName,64);if(lstrcmpi(szClassName,_T("Ed
15、it") = 0) /是Edit 控件DWORD dwStyle = pWnd->GetStyle();if(dwStyle & ES_MULTILINE) = ES_MULTILINE) /多行edit控件pDC->SetTextColor(m_clrText);return hbr;elsepDC->SetTextColor(m_clrText);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd;else /不是編輯控件if(pWnd->GetDlgCtrlID() = IDC_STC_
16、REDTEXT)pDC->SetTextColor(RGB(255,0,0);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd;else if(pWnd->GetDlgCtrlID() = IDC_STC_BLUETEXT)pDC->SetTextColor(RGB(0,0,255);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd;else if(pWnd->GetDlgCtrlID() = IDC_STC_BLUETEXTWHITEBACK)p
17、DC->SetTextColor(RGB(0,0,255);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brControlBkgnd1;else if(pWnd->GetDlgCtrlID() = IDC_CHK_GREEN)pDC->SetTextColor(RGB(0,255,0);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd;else if(pWnd->GetDlgCtrlID() = IDC_RAD_BLUE)pDC->SetTextCol
18、or(RGB(0,0,255);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd;else if(pWnd->GetDlgCtrlID() = IDC_CHK_GREEN2)pDC->SetTextColor(RGB(0,255,0);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brControlBkgnd2;else if(pWnd->GetDlgCtrlID() = IDC_RADIO2)pDC->SetTextColor(RGB(0,0,255);pD
19、C->SetBkMode(TRANSPARENT);return (HBRUSH)m_brControlBkgnd2;elsepDC->SetTextColor(m_clrText);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_brBkgnd; 現(xiàn)在看看效果:圖.5 修改OnCtlColor之后的效果上面的代碼是根據(jù)控件ID來(lái)設(shè)置顏色,還可以根據(jù)控件的類型統(tǒng)一設(shè)置某種控件的顏色,這就要用到nCtlColor參數(shù),nCtlColor參數(shù)用來(lái)指明發(fā)送這個(gè)通知消息的控件的類型,nCtlColor可以是以下取值:CTLCOLOR_BTN
20、CTLCOLOR_DLG CTLCOLOR_EDIT CTLCOLOR_LISTBOX CTLCOLOR_MSGBOXCTLCOLOR_SCROLLBAR CTLCOLOR_STATIC 第三步:使用位圖作對(duì)話框的背景使用位圖作為對(duì)話框的背景也很簡(jiǎn)單,就是在OnEraseBkgnd中用位圖填充客戶區(qū),只是在OnCtlColor中需要注意返回空畫刷代替原來(lái)的畫刷,返回空畫刷是為了阻止控件繪制自己的背景,從而破壞位圖背景的完整性,但是有時(shí)候返回空畫刷會(huì)對(duì)其他控件產(chǎn)生不良影響,所以我們只處理了CTLCOLOR_BTN和CTLCOLOR_STATIC兩種類型的消息:HBRUSH CBmpBkgndDl
21、g:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) HBRUSH hbr = CDialog:OnCtlColor(pDC, pWnd, nCtlColor);if(nCtlColor = CTLCOLOR_BTN | nCtlColor = CTLCOLOR_STATIC)pDC->SetTextColor(RGB(0,0,255);pDC->SetBkMode(TRANSPARENT);return (HBRUSH)m_HollowBrush;pDC->SetTextColor(RGB(0,0,255);pDC->S
22、etBkMode(TRANSPARENT);return hbr;下面是使用位圖背景和空畫刷的效果:圖.6 使用位圖背景的效果第四步:?jiǎn)为?dú)處理按鈕控件現(xiàn)在看來(lái)按鈕控件還是影響整體效果,WM_CTLCOLORBTN好像對(duì)于push button類型的按鈕控件沒(méi)有效果,不過(guò)push button也是支持自畫的,在使用自畫按鈕之前,我們先來(lái)看看控件自畫的原理。Windows的控件都有默認(rèn)的外觀,但是許多控件有支持“自畫”,也就是讓用戶定制控件的外觀,當(dāng)給一個(gè)控件指定自畫的樣式之后,控件在重畫自己的時(shí)候向父窗口發(fā)送WM_MEASUREITEM和WM_DRAWITEM消息,父窗口響應(yīng)這兩個(gè)消息,定位控件
23、的大小并繪制控件,從而使控件有定制的外觀。但是每個(gè)控件的自畫都由父窗口完成加重了父窗口的負(fù)擔(dān),也不利于代碼重用,所以,MFC對(duì)這些消息進(jìn)行了反射處理,就是將消息發(fā)還位控件,由控件響應(yīng)消息,自己繪制,這樣將自畫代碼封裝在控件類中,提高了代碼的重用性。很多MFC的控件類都自己處理這兩個(gè)消息,派生類可以重載MeasureItem和DrawItem自己畫控件的外觀,CButton就是這樣的控件類?,F(xiàn)在就來(lái)做一個(gè)自畫的按鈕類,首先從CButton派生一個(gè)類,我們命名為CSMButton,然后重載DrawItem和PreSubclassWindow,重載PreSubclassWindow的原因是在CSMButton子類化按鈕控件之前先給按鈕添加BS_OWNERDRAW樣式,否則按鈕就不會(huì)向父窗口發(fā)送WM_DRAWITEM消息,MFC的消息反射就不會(huì)發(fā)生,我們的DrawItem就不會(huì)被調(diào)用,嗯,后果很嚴(yán)重。當(dāng)然也可以讓CSMButton的使用者自己給按鈕添加BS_OWNERDRAW樣式,但是會(huì)讓人覺(jué)得沒(méi)水平,嗯,后果也很嚴(yán)重。接下來(lái)添加對(duì)WM_CAPTURECHANGED、WM_MOUSEMOVE、WM_SETCURSOR和WM_KILLFOCUS四個(gè)消息的響應(yīng)函數(shù),對(duì)這四個(gè)消息的響應(yīng)是為了給按鈕增加更多的功能,比如使按
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- T-ZRCMA 001-2024 城市軌道交通智慧實(shí)訓(xùn)系統(tǒng)技術(shù)規(guī)范
- 二零二五年度餐飲店面租賃合同含節(jié)假日促銷活動(dòng)
- 二零二五年度個(gè)人擔(dān)保合同-個(gè)人理財(cái)產(chǎn)品擔(dān)保服務(wù)條款
- 二零二五年度農(nóng)村墓地選購(gòu)與祭祀活動(dòng)組織合同
- 二零二五年度茶飲品牌全國(guó)使用許可合同
- 二零二五年度互聯(lián)網(wǎng)保險(xiǎn)產(chǎn)品銷售委托理財(cái)服務(wù)協(xié)議
- 二零二五年度棋牌室合作伙伴關(guān)系管理與維護(hù)合同
- 2025年度順豐員工勞動(dòng)合同爭(zhēng)議解決機(jī)制合同
- 二零二五年度個(gè)人合同范本:智能家居控制系統(tǒng)研發(fā)合作合同
- 二零二五年度新型工業(yè)園區(qū)委托中介代理出租服務(wù)協(xié)議
- 2025年高考百日誓師大會(huì)校長(zhǎng)致辭(二)
- 2025年河南機(jī)電職業(yè)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(kù)及參考答案
- 2025年黑龍江能源職業(yè)學(xué)院?jiǎn)握新殬I(yè)傾向性測(cè)試題庫(kù)完整
- 學(xué)校垃圾處理運(yùn)輸服務(wù)合同
- 廣西2025年01月南寧市良慶區(qū)公開(kāi)考試招考專職化城市社區(qū)工作者筆試歷年典型考題(歷年真題考點(diǎn))解題思路附帶答案詳解
- 注塑產(chǎn)品生產(chǎn)流程
- 統(tǒng)編版(2025)七年級(jí)下冊(cè)道德與法治教學(xué)計(jì)劃
- 七年級(jí)數(shù)學(xué)下冊(cè) 第11章 單元測(cè)試卷(蘇科版 2025年春)
- 2024年天津市建筑安全員A證考試題庫(kù)及答案
- 《人力資源管理》全套教學(xué)課件
- 空白房屋裝修合同范本
評(píng)論
0/150
提交評(píng)論