




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、12l模仿MFC用C+類(lèi)對(duì)Windows主函數(shù)進(jìn)行封裝 l應(yīng)用程序類(lèi)CWinApp及其派生類(lèi) l窗口類(lèi)CFrameWnd及其派生類(lèi) lCCmdTarget類(lèi) lMFC消息映射 3 對(duì)例1-2的程序的主函數(shù)進(jìn)行分析后,就會(huì)知道,主函數(shù)的任務(wù)是創(chuàng)建并顯示窗體和實(shí)現(xiàn)消息循環(huán)。如果用面向?qū)ο蟮乃枷雭?lái)考慮的話,主函數(shù)的函數(shù)體可以看成一個(gè)對(duì)象應(yīng)用程序類(lèi)對(duì)象,而其中的窗體應(yīng)該是嵌入在這個(gè)應(yīng)用程序類(lèi)對(duì)象中的另一個(gè)對(duì)象窗體類(lèi)對(duì)象。因此,為了形成程序框架,應(yīng)該聲明兩個(gè)類(lèi):應(yīng)用程序類(lèi)和窗體類(lèi)。4l窗體類(lèi)應(yīng)該具有窗口類(lèi)屬性的定義,窗口類(lèi)的注冊(cè),窗口的創(chuàng)建和顯示等與窗口相關(guān)的功能.因此,窗體類(lèi)只要把窗體句柄和對(duì)窗口操作
2、的API函數(shù)封裝到一起就可以了.于是,窗體聲明為:5窗口類(lèi):class CFrameWndpublic:HWND hWnd;public:int RegisterWindow();void Create(LPCTSTR lpClassName,LPCTSTR lpWindowName);void ShowWindow(int nCmdShow);void UpdateWindow();數(shù)據(jù)成員創(chuàng)建窗口定義及注冊(cè)窗口類(lèi)顯示與更新窗口6Int CFrameWnd:RegisterWindow( )WNDCLASS wc;wc.style=0;wc.lpfnWndProc=WndProc;wc.cb
3、ClsExtra=0;wc.cbWndExtra=0;wc.hInstance=hInstance;wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);wc.hCursor=LoadCursor(NULL,IDC_ARROW);wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName=NULL;wc.lpszClassName=lpszClassName;return RegisterClass(&wc);7void CFrameWnd:Create(LPCTSTR lpClassNam
4、e,LPCTSTR lpWindowName)RegisterWindow(); hInst=hInstance;hWnd=CreateWindow(lpszClassName,lpWindowName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT, 0,NULL,NULL, hInstance,NULL);8void CFrameWnd:ShowWindow(int nCmdShow):ShowWindow(hWnd, nCmdShow);void CFrameWnd:UpdateWindow():UpdateWindow(hWnd);9
5、 如果把主函數(shù)中的函數(shù)體看成一個(gè)對(duì)象,并把它叫做應(yīng)用程序,則還應(yīng)該聲明一個(gè)應(yīng)用程序類(lèi)CWinApp.在這個(gè)應(yīng)用程序類(lèi)中,至少有一個(gè)窗體類(lèi)對(duì)象m_pMainWnd作為類(lèi)的數(shù)據(jù)成員.這個(gè)類(lèi)還應(yīng)該有成員函數(shù)InitInstance和Run. InitInstance: 創(chuàng)建窗體對(duì)象m_pMainWnd,并通過(guò)它調(diào)用窗口類(lèi)成員函數(shù)注冊(cè),創(chuàng)建,顯示. Run: 消息循環(huán)消息循環(huán)10應(yīng)用程序類(lèi):class CWinApppublic:CFrameWnd* m_pMainWnd;public:BOOL InitInstance (int nCmdShow);int Run();以窗口類(lèi)的對(duì)象作為數(shù)據(jù)成員在初
6、始化函數(shù)中創(chuàng)建及顯示窗口消息循環(huán)11/應(yīng)用程序類(lèi)的成員函數(shù)BOOL CWinApp:InitInstance(int nCmdShow)m_pMainWnd=new CFrameWnd;m_pMainWnd-Create(NULL,封裝的Windows程序);m_pMainWnd-ShowWindow(nCmdShow);m_pMainWnd-UpdateWindow();return TRUE;12int CWinApp:Run()while (GetMessage(&msg, NULL, 0, 0) TranslateMessage(&msg);DispatchMessage(&msg);
7、return msg.wParam;CWinApp:CWinApp()delete m_pMainWnd;13 有了應(yīng)用程序類(lèi)和窗體類(lèi),在設(shè)計(jì)Windows程序時(shí),就可以用CWinApp類(lèi)定義一個(gè)全局對(duì)象theApp,而在主函數(shù)的函數(shù)體中逐個(gè)的調(diào)用CWinApp對(duì)象theApp的成員函數(shù)。14/程序員定義的WinApp的對(duì)象theAppCWinApp theApp;/主函數(shù)int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)int ResultCode=
8、-1;theApp.InitInstance(nCmdShow);return ResultCode=theApp.Run();15 從程序中可以看出,如果把窗體類(lèi)CFrameWnd和應(yīng)用程序類(lèi)CWinApp預(yù)先定義后,內(nèi)置在一個(gè)類(lèi)庫(kù)中,那么,其它程序設(shè)計(jì)人員就可以直接使用這些類(lèi)來(lái)定義對(duì)象,而沒(méi)有必要自己來(lái)聲明類(lèi)了。更進(jìn)一步,如果再制作一個(gè)程序設(shè)計(jì)向?qū)?,把主函?shù)也自動(dòng)創(chuàng)建出來(lái),那么,程序員的工作只剩下兩項(xiàng):定義一個(gè)應(yīng)用程序類(lèi)的全局對(duì)象theApp和編寫(xiě)窗口函數(shù)。這樣就大大減輕了程序設(shè)計(jì)人員的工作量。16l利用C+類(lèi)的繼承性和多態(tài)性,程序員可以在已有的類(lèi)的基礎(chǔ)上派生自己的類(lèi)。這樣,程序員就可以在
9、派生類(lèi)中添加添加自己需要的成員,同時(shí)也可以對(duì)基類(lèi)的函數(shù)進(jìn)行重新定義重新定義(重寫(xiě)),以滿足不同應(yīng)用程序的需要。 171.虛函數(shù)的應(yīng)用 例2-2 用CWinApp的派生類(lèi)CMyApp編寫(xiě)的程序。2.獲得應(yīng)用程序?qū)ο笾羔樀暮瘮?shù) 在CWinApp的聲明中增加如下代碼:CWinApppublic:CWinApp * m_pCurrentApp;public:CWinApp(); ;CWinApp:CWinApp()m_pCurrentApp=this;18這樣,當(dāng)程序員定義了一個(gè)應(yīng)用程序?qū)ο蠛?,m_pCurrentApp就指向了這個(gè)對(duì)象。為了在主函數(shù)中獲得這個(gè)對(duì)象,應(yīng)該再設(shè)計(jì)一個(gè)能獲得應(yīng)用程序類(lèi)對(duì)象指
10、針的全局函數(shù)AfxGetApp():CWinApp *AfxGetApp()Return theApp.m_pCurrentApp;這樣,如果在主函數(shù)中定義一個(gè)CWinApp*類(lèi)型的指針pApp,然后令pApp=AfxGetApp(),那么在主函數(shù)中就可以使用pApp來(lái)調(diào)用應(yīng)用程序?qū)ο蟮母鱾€(gè)成員函數(shù)。19例2-3 應(yīng)用窗體和應(yīng)用程序類(lèi)的派生類(lèi)的完整程序?qū)嵗?0 在Windows SDK程序中,用窗口函數(shù)的switch-case結(jié)構(gòu)來(lái)查找消息處理程序。而MFC程序則希望把每個(gè)case中的消息的處理程序段作為一個(gè)函數(shù)消息處理函數(shù),把他們封裝在各個(gè)類(lèi)中 。21 在類(lèi)CCmdTarget類(lèi)中封裝了窗
11、口函數(shù),而窗口類(lèi)CFrameWnd則以CCmdTarget類(lèi)為基類(lèi)來(lái)派生。在類(lèi)CCmdTarget中,單獨(dú)聲明每個(gè)消息各自對(duì)應(yīng)的處理函數(shù),而在AfxWndProc的各個(gè)case中,調(diào)用CCmdTarget類(lèi)中的這些消息處理函數(shù)。這樣就可以把一些允許程序員重新定義的消息處理函數(shù)設(shè)置為虛函數(shù),使程序設(shè)計(jì)人員可以在派生類(lèi)中編寫(xiě)需要的消息處理代碼。例2-4 在例2-3的基礎(chǔ)上,對(duì)消息處理函數(shù)進(jìn)行簡(jiǎn)單的封裝。22 上面對(duì)消息封裝的方法雖然可行,但為了使應(yīng)用程序代碼更具有可讀性,MFC使用了一個(gè)叫做消息映射的機(jī)制來(lái)實(shí)現(xiàn)消息響應(yīng)函數(shù)的封裝.1.類(lèi)的消息映射表類(lèi)的消息映射表在類(lèi)中聲明如下形式的消息響應(yīng)函數(shù) a
12、fx_msg void 消息處理函數(shù)名();然后定義一個(gè)AFX_MSGMAP_ENTRY類(lèi)型的數(shù)組_messageEntries。23struct AFX_MSGMAP_ENTRYUINT nMessage; / Windows消息UINT nCode; UINT nID; UINT nLastID; UINT nSig; AFX_PMSG pfn; / 消息函數(shù)指針;數(shù)組的每一個(gè)元素都含有數(shù)組的每一個(gè)元素都含有消息的標(biāo)識(shí)和這個(gè)消息對(duì)消息的標(biāo)識(shí)和這個(gè)消息對(duì)應(yīng)的消息處理函數(shù)名應(yīng)的消息處理函數(shù)名24為了把類(lèi)族中各個(gè)類(lèi)的消息映射表連接成一個(gè)大表,要求再建立一個(gè)具有如圖所示的鏈表,從而把各個(gè)類(lèi)的消息函
13、數(shù)映射連接起來(lái),形成一個(gè)大表.這個(gè)大表的作用就是根據(jù)消息取得消息處理函數(shù),所以這個(gè)大表在MFC中叫做消息映射表.2526 根據(jù)上面的敘述,設(shè)計(jì)一個(gè)需要響應(yīng)消息的類(lèi)時(shí),必須在類(lèi)中聲明一個(gè)消息映射表,而且要在類(lèi)的外部實(shí)現(xiàn)。為了簡(jiǎn)化程序員的工作,MFC把完成上述功能的代碼封裝在下述4個(gè)宏中: (1) 使用宏DECLARE_MESSAGE_MAP() 這個(gè)宏在類(lèi)的聲明中使用,用來(lái)聲明消息映射表,并在該宏之前聲明消息處理函數(shù)。 (2) BEGIN_MESSAGE_MAP 這個(gè)宏在類(lèi)聲明外使用,所有消息映射宏都添加在這里,格式為: BEGIN_MESSAGE_MAP(類(lèi)名稱(chēng)類(lèi)名稱(chēng),基類(lèi)名稱(chēng)基類(lèi)名稱(chēng)) 27
14、(3)ON_消息類(lèi)型消息類(lèi)型 這個(gè)宏使用在宏BEGIN_MESSAGE_MAP后面后面,依次填寫(xiě)類(lèi)消息依次填寫(xiě)類(lèi)消息映射表中各個(gè)元素映射表中各個(gè)元素,這個(gè)宏有如下幾種格式這個(gè)宏有如下幾種格式: 對(duì)于標(biāo)準(zhǔn)窗口消息,程序員需要把窗口消息的宏定義寫(xiě)在ON_后面,如: ON_WM_LBUTTONDOWN() 這樣,系統(tǒng)會(huì)自動(dòng)把該消息對(duì)應(yīng)的消息處理函數(shù)名 afx_msg OnLbuttonDown()寫(xiě)入類(lèi)消息映射表. 對(duì)于菜單選項(xiàng),快捷鍵和控件產(chǎn)生的windows命令消息ON_COMMAND,在填寫(xiě)消息映射表時(shí)需要兩個(gè)參數(shù): ON_COMMAND(消息ID,消息處理函數(shù)名) ON_COMMAND(IDM_FILENEW,OnFileNew)lNotification消息是由按鈕、文本編輯框等控件產(chǎn)生的消息,由于控件種類(lèi)很多,此實(shí)現(xiàn)消息映射宏的格式也不盡形同。 ON_BN_CLICKED(,) ON_CBN_DBLCLK(,) ON_EN_DBLCLK(,)28(4) END_MESSAGE_MAP 消息處理函數(shù)表的結(jié)束宏 例2-5 用MFC類(lèi)庫(kù)設(shè)計(jì)的含有消息映射的Windows應(yīng)用程序。29CWinApp類(lèi)是MFC對(duì)W
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 耐火材料的生產(chǎn)工藝優(yōu)化考核試卷
- 《六年級(jí)家長(zhǎng)會(huì)課件》2
- 膠合板制造綜合課程資源考核試卷
- 《數(shù)學(xué)分析的基本概念》課件(新人教A版必修)
- 電視機(jī)的安裝和保養(yǎng)技巧考核試卷
- 航空法律法規(guī)與政策理解考核試卷
- 火車(chē)站應(yīng)急預(yù)案制定考核試卷
- 絕緣制品在建筑行業(yè)的應(yīng)用考核試卷
- 生物識(shí)別與安全認(rèn)證軟件考核試卷
- 大學(xué)生創(chuàng)業(yè)教育體系構(gòu)建
- 秸稈買(mǎi)賣(mài)協(xié)議書(shū)模板
- 人教版小學(xué)二年級(jí)下冊(cè)數(shù)學(xué) 第6單元 第6課時(shí) 解決問(wèn)題(2) 課件
- 2024年延安通和電業(yè)有限責(zé)任公司招聘考試真題
- 2025年中國(guó)礦山支護(hù)設(shè)備行業(yè)市場(chǎng)規(guī)模及投資前景預(yù)測(cè)分析報(bào)告
- 新形勢(shì)下如何抓好“兩個(gè)經(jīng)常性”工作
- 監(jiān)控立桿采購(gòu)合同協(xié)議
- 貼改色膜合同協(xié)議
- 清理罐車(chē)合同協(xié)議
- 電工比武大賽試題及答案
- 郵政儲(chǔ)蓄大堂引導(dǎo)員培訓(xùn)
- 社工小組協(xié)議書(shū)范例
評(píng)論
0/150
提交評(píng)論