1.前言
我們在做窗口程序時,難免有時候會軟件添加一些背景顏色或者圖片,來對其進行美化,如果只有一個窗口,可能這還比較好辦.如果窗口很多,而且我們又想讓它們的界面風格保持一致,那麼我們應該怎麼去做呢?或許有朋友會講,對每個對話框窗口進行美化不就行了嗎?如果要求它們的界面保持一致的話,使用相同的代碼對各自的對話框進行美化,這不就能達到風格統一的效果嗎?
是的,的確,這樣確實也能達到我們的要求,但不知道各位有沒有想過,當我們的對話框足夠多,就意味着我們需要將同一份代碼複製足夠多份到足夠多的對話框程序中,如果那天我們對風格不滿意了,需要對它們進行修改,而且風格依然要求統一起來,如果遇到這樣的情況,我們再使用前面 的方法去做,或許這會兒我們就會感到該方法的的弊端,因爲我們需要去修改每一個對話框程序中的代碼.那麼究竟用什麼方法才能避免這種事情呢?
答案是:充分利用面向對象的思想,採用繼承機制來幫我們完成這一工作.
2.設計思想:
平常情況下, 我們創建一個對話框,那麼我們會從CDialog類中派生一個類來與之相關聯,如果 我們需要更改對話框的風格,我們就需要在該派生類中來完成對該對話框風格的更改.
當需要定義多個對話框時,我們可以先從CDialog類中派生一個自己的類CMyDialog,然後再爲對話框創建關聯類時,我們只需要把對話框關聯類的基類修改成CMyDialog,那麼在CMyDialog中定義的所有方法都會被所有繼承它的子類所享有,當我們需要對對話框的界面風格進行統一制定時,我們只需要在CMyDialog裏對風格進行設置,其它的對話框所風格則會自己繼承.當需要對風格進行更改時,我們只需要修改CMyDialog中定義風格的代碼即可完成對所有對話框的界面風格的更改.
3.舉例說明
1.首先我們創建一個基於對話框的MFC應用程序.工程名字爲phpoo.
2.然後我們新建一個類,該類從CDialog中派生,類名爲CMyDig.(注意:當我們點擊確定時,這裏會出現一個提示信息,提示說"沒有爲該類創建一個資源對話框,希望我們先創建資源對話框後再創建該類,否則將會爲其關聯一個不合法的資源ID,是否斷續",我們選擇是).
3.修改CPhpooDlg類的基類爲CMyDig,同時修改CPhpooDlg構造函數的初始化列表爲 CMyDlg(CPhpooDlg::IDD, pParent)(因爲現在CPhpooDlg已經不再從CDialog派生,而是從CMyDlg類派生而來,所以這時我們需要向它的基類CMyDlg傳遞資源相關的參數.
代碼如下:
class CPhpooDlg : public CMyDlg//將CPhpooDlg基類修改爲CMyDlg
CPhpooDlg::CPhpooDlg(CWnd* pParent /*=NULL*/) : CMyDlg(CPhpooDlg::IDD, pParent)//修改CPhpooDlg構造函數的初始化列表
4.將CMyDlg類頭文件MyDlg.h加入到CPhpooDlg類的頭文件中.
5.將CMyDlg中enum { IDD = _UNKNOWN_RESOURCE_ID_ };去掉。並重載一個構造函數,將設置和先前默認構造函數相同的初始化列表,用來接受派生類傳遞過來的ID。同時將默認構造函數的初始化列表去掉。因爲這裏只使用我們所重載的構造函數。向基類的構造函數的初始化由現在的重載構造函數來完成。
代碼如下:
/** * 重載構造函數,用來接收派生類所傳遞的資源ID等參數, */ CMyDlg::CMyDlg(UINT nIDTemplate, CWnd *pParentWnd) : CDialog(nIDTemplate, pParentWnd)//設置初始化列表對CDialog函數進行初始化 { }
//去掉初始化列表 CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
6.接下來爲CMyDlg定義背景,這裏我們將設置一張圖片作爲該對話框的背景。
首先找一張圖片,拷入到資源文件夾下,並將其導入到資源列表中。
接下來在CMyDlg類中添類型爲CBrush的成員變量,用來保存我們的背景。
CBrush m_brush;//定義畫刷句柄
在構造函數中創建位圖畫刷.
/**
* 重載構造函數,用來接收派生類所傳遞的資源ID等參數,
*/
CMyDlg::CMyDlg(UINT nIDTemplate, CWnd *pParentWnd)
: CDialog(nIDTemplate, pParentWnd)//設置初始化列表對CDialog函數進行初始化
{
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);//load pic
m_brush.CreatePatternBrush(&bmp);//使用指定的位圖來創建一把畫刷
bmp.DeleteObject();
}
添加ON_WM_CTLCOLOR事件響應函數,將返回值改爲m_brush.
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here // TODO: Return a different brush if the default is not desired return m_brush;//返回我們定義的畫刷 }
由於在子類中CMyDlg的OnCtlColor不會自動被調用,所以我們需要在子類中顯示的調用該函數。
創建CPhpooDlg的ON_WM_CTLCOLOR事件響應函數。並將返回CMyDlg所擁有的畫刷。代碼如下:
HBRUSH CPhpooDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CMyDlg::OnCtlColor(pDC, pWnd, nCtlColor);//返回CMyDlg而不是CDialog的畫刷 // TODO: Change any attributes of the DC here // TODO: Return a different brush if the default is not desired return hbr; }
我們這裏編譯運行,就會發現,這裏的對話框背景已經變成了我們所指定的背景了。
上面我們只創建了一個對話框,如果我們需要創建更多的對話框,我們只需要簡簡單單的修改幾處,就能很方便的將這些對話框的風格進行統一進來。這幾處是:對話框的基類,修改對話框構造函數的初始化列表,爲ON_WM_CTLCOLOR添加響應函數,並返回CMyDlg的畫刷。