MFC電子課件:實踐教程第三章第二版_第1頁
MFC電子課件:實踐教程第三章第二版_第2頁
MFC電子課件:實踐教程第三章第二版_第3頁
MFC電子課件:實踐教程第三章第二版_第4頁
MFC電子課件:實踐教程第三章第二版_第5頁
已閱讀5頁,還剩175頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第三章 MFC程序設(shè)計,本章的內(nèi)容,簡潔而不失完整性:由應(yīng)用程序向?qū)Ы⒊绦蚩蚣埽少Y源編輯器建立用戶界面,由類向?qū)Ы⒊蓡T變量、消息映射和處理函數(shù),加上文檔序列化和注冊 MFC包含了所有與系統(tǒng)相關(guān)的類(包括圖形用戶界面相關(guān)的類),其中封裝了大多數(shù)的API函數(shù),提供了應(yīng)用程序框架和開發(fā)應(yīng)用程序的工具如應(yīng)用程序向?qū)?、類向?qū)А⒖梢暬Y源設(shè)計等高效工具,用消息映射處理消息響應(yīng),大大簡化了Windows應(yīng)用程序的開發(fā)工作,使程序員可以從繁重的編程工作中解脫,提高工作效率。,3.1.MFC程序設(shè)計簡介 3.2.MFC 程序設(shè)計 3.3.用戶界面資源的應(yīng)用 3.4.對話框的應(yīng)用 3.5.基于對話框的應(yīng)用程

2、序設(shè)計實例 3.6.文本和圖形輸出 3.7.文檔的保存 3.8. MDI應(yīng)用程序設(shè)計,目錄,3.1 MFC程序設(shè)計簡介,MFC類庫 基礎(chǔ)類 (已在第二章中介紹) 宏、全局變量及全局函數(shù) 應(yīng)用程序框架,3.1.1 MFC定義的宏、全局函數(shù)及全局變量,類庫,1. MFC提供的主要宏:,消息映射宏:聲明消息映射表宏DECLARE_MESSAGE_MAP、消息映射定義宏BEGIN_MESSAGE_MAP和END_MESSAGE_MAP消息映射表入口宏ON_消息名。(本章只介紹消息映射宏),3.1.1 MFC定義的宏、全局函數(shù)及全局變量,動態(tài)MFC對象宏 DECLARE_DYNAMIC和IMPLEMEN

3、T_DYNAMIC 動態(tài)創(chuàng)建對象宏 DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE 運行時類宏: RUNTIME_CLASS 序列化宏: DECLARE_SERIAL和IMPLEMENT_SERIAL 診斷服務(wù)宏: ASSERT、VERIFY 跟蹤服務(wù)宏: TRACE 異常處理宏: THROW,3.1.1 MFC定義的宏、全局函數(shù)及全局變量,MFC提供一些不屬于任何類的全局函數(shù),函數(shù)名以Afx開頭,可以被應(yīng)用程序中的所有類和函數(shù)所調(diào)用。如:AfxAbort(),無條件終止一個應(yīng)用程序的執(zhí)行;AfxGetAppName(),返回指向應(yīng)用程序名的字符串指針;AfxWin

4、Init(),由WinMain()調(diào)用,對MFC應(yīng)用程序進行圖形用戶界面(GUI)的初始化等等。,3. 全局變量,全局變量名以afx開頭,如afxTraceFlag、afxDump等,主要與異常處理有關(guān)。,2. 全局函數(shù),3.1.2 MFC命名規(guī)則,匈牙利命名法規(guī)定:,變量名以一個或多個小寫字母開頭作為前綴,標識變量的數(shù)據(jù)類型;,類型標識后是若干個單詞,標識變量含義,每個單詞以大寫字母開頭,其余字母小寫;,MFC中所有類及自定義類都以C開頭;,類成員變量以m_為前綴,下劃線后是變量名等等。,表3.1 命名規(guī)則,h,MFC提供了構(gòu)造Windows應(yīng)用程序的框架,它不僅為應(yīng)用程序建立標準的結(jié)構(gòu),生

5、成一系列起動文件,還提供標準的圖形用戶界面如菜單、工具欄、狀態(tài)條等供開發(fā)人員在程序中補充完善,開發(fā)人員只需要完成針對特定應(yīng)用的代碼。使用應(yīng)用程序框架的應(yīng)用程序代碼小,運行速度快,它提供的工具也降低了編碼的難度。,3.1.3 應(yīng)用程序框架介紹,程序的數(shù)據(jù)儲存在文檔類中(作為文檔類的數(shù)據(jù)成員),是對數(shù)據(jù)的抽象表示。數(shù)據(jù)顯示由視圖負責(zé),視圖是程序窗口的客戶區(qū),框架窗口是客戶區(qū)的框架,程序數(shù)據(jù)顯示在窗口,用戶通過視圖與程序交互。 一個文檔可以對應(yīng)多個不同視圖;而一個視圖一般只對應(yīng)一個文檔。當(dāng)文檔數(shù)據(jù)發(fā)生變化時,視圖顯示的狀態(tài)也會隨之變化;對于多個視圖的情況,基于同一文檔的多個視圖的顯示同步變化。,1.

6、文檔-視圖結(jié)構(gòu),文檔視圖結(jié)構(gòu)提供一種連續(xù)處理數(shù)據(jù)的方式,使應(yīng)用程序的數(shù)據(jù)與數(shù)據(jù)的顯示分開處理。,文檔、視圖及框架的關(guān)系:,圖3.1,2. 單文檔界面應(yīng)用,單文檔界面應(yīng)用程序簡稱SDI(Single Document Interface),只允許一個框架窗口存在,每次只能創(chuàng)建和擁有一個文檔對象,也只允許打開一個文檔。 SDI各類 關(guān)系圖,可將文檔比作一個文件袋,專門用于保存文件數(shù)據(jù),需要看時需從文件袋(文檔)中取出來,放到桌面(視圖)上看。,表3.2 基于文檔/視圖關(guān)系的SDI應(yīng)用中的類,返回,應(yīng)用程序類,框架類( 窗口框架),資源(決定用戶 界面的顯示),視圖類 (顯示數(shù)據(jù)并 與用戶交互),文

7、檔類 (保存數(shù)據(jù)),單文檔模板,返回,應(yīng)用程序類 CDocManager* m_pDocManager,框架類( 窗口框架),資源(決定用戶 界面的顯示),m_pDocument 視圖類(顯示數(shù)據(jù) 并與用戶交互),文檔類(保存數(shù)據(jù)) m_pDocTemplate m_viewList,返回,單文檔模板 CRuntimeClass*m_pDocClass CRuntimeClass*m_pFrameClass CRuntimeClass*m_pViewClass UINT m_nIDResource,多文檔界面應(yīng)用簡稱MDI(Multiple Document Interface),允許有多個文

8、檔類、視圖類和多個文檔模板CMultiDocTemplate(建立多種文檔-視圖-子框架關(guān)系)存在,運行時允許打開多個MDI子框架窗口,擁有各自的文檔和視圖對象。示例 關(guān)系圖,在打開的多個子窗口中,只有一個活動窗口,應(yīng)用程序菜單和工具欄的所有的命令都是針對活動窗口的。,3.多文檔界面應(yīng)用,主 框 架, 其它文檔模板,返回,CDocManager,應(yīng)用程序類 CDocManager* m_pDocManager,文檔/視圖結(jié)構(gòu)可以充分發(fā)揮應(yīng)用程序框架和MFC的優(yōu)勢,是MFC應(yīng)用程序的核心,但使用它也要付出運行效率和代碼增大的代價。,文檔/視圖結(jié)構(gòu)對應(yīng)用程序來說并不是必不可少的,有兩種常見的非文檔

9、/視圖結(jié)構(gòu)應(yīng)用。,4. 非文檔/視圖結(jié)構(gòu)應(yīng)用,常見非文檔/視圖結(jié)構(gòu)應(yīng)用:,(1).基于對話框的應(yīng)用,它包含一個CWinApp對象和一個模態(tài)對話框,對話框負責(zé)數(shù)據(jù)的存儲和顯示 。關(guān)系圖,(2).SDI或MDI應(yīng)用,都可以不包含文檔對象,SDI包含一個CWinApp對象,一個框架窗口對象和一個從CWnd派生的CChildView視圖對象,視圖對象負責(zé)數(shù)據(jù)的顯示,MDI應(yīng)用還包括一個子框架窗口。,對話框類 作為應(yīng)用程序主窗口 負責(zé)保存和顯示數(shù)據(jù),應(yīng)用程序類,返回,Dialog-based Application,主框架,應(yīng)用程序主窗口,CChildView視圖類 負責(zé)保存和顯示數(shù)據(jù),應(yīng)用程序類,SD

10、I Application, None Doc/View,返回,子框架, 視圖框架窗口,CChildView 視圖類,應(yīng)用程序類,子框架, 視圖框架窗口,CChildView 視圖類,主框架,應(yīng)用程序主框架窗口,MDI Application, None Doc/View,返回,圖3.2 MFC應(yīng)用程序開發(fā)過程,類向?qū)?集成開發(fā)環(huán)境,應(yīng)用程序向?qū)?資源編輯器,Create,.def,.cpp .h,.dsw .dsp,.ico,.rc,.bmp,源文件,資源文件,編譯,.obj,Build,資源編譯,.res,應(yīng)用程序,5. MFC應(yīng)用程序創(chuàng)建,6.最簡單的MFC應(yīng)用程序示例,對于一個MFC應(yīng)

11、用程序來說,只有CWinApp的派生對象是必不可少的,其它類均可視情況進行取舍。下例是一個最簡單的MFC應(yīng)用程序。 例:顯示一個消息框。 (1).創(chuàng)建工程,工程類型選擇Win32 Application,工程名為Ex3_0; (2).創(chuàng)建C+源文件,文件名Ex3_0.cpp,內(nèi)容如下:,#include class CEx3_0App: public CWinApp /CWinApp派生類 public: virtual BOOL InitInstance() MessageBox(NULL,”SimplistMFC Application.”, ”Ex3_0”,MB_OK); return

12、TRUE; ; CEx3_0App theApp; /全局變量,代表應(yīng)用程序本身,CWinApp:InitInstance()虛函數(shù)完成應(yīng)用程序的初始化工作,派生的應(yīng)用程序類都要重載此函數(shù)進行初始化,如完成主框架窗口的構(gòu)造,窗口定義顯示等工作。,(3).設(shè)置使用MFC。 選擇Project|Settings菜單項,選擇General頁面,在Microsoft Foundation Classes組合框中選擇Use MFC in a shared DLL。 (4).編譯生成并運行此工程,結(jié)果顯示一個消息框,如下圖:,圖3.3 最簡單MFC應(yīng)用示例,3.2.MFC 程序設(shè)計,MFC應(yīng)用程序的執(zhí)行過

13、程(參見圖3.4):,1.構(gòu)造全局對象CWinApp派生類對象;,2.運行由應(yīng)用程序框架提供的WinMain函數(shù);,圖3.4 MFC應(yīng)用程序的執(zhí)行過程,3.在WinMain中,通過afxGetApp()獲得全局對象的指針pApp,調(diào)用全局函數(shù)AfxWinInit() ,為CWinApp的成員 變量m_hInstance, m_hPrevInstance, m_lpCmdLine, m_nCmdShow賦初值; 然后調(diào)用pApp-InitApplication() ,這是CWinApp的虛函數(shù),一般不需要改寫; 調(diào)用 pApp-InitInstance() ,每個程序都必需改寫這個函數(shù),進行應(yīng)用

14、程序初始化;,4.在InitInstance()函數(shù)中,先用new構(gòu)造一個CFrameWnd派生類對象,其構(gòu)造函數(shù)又調(diào)用Create(),創(chuàng)建主窗口,MFC依此自動為應(yīng)用程序注冊窗口類; 調(diào)用ShowWindow()顯示窗口,調(diào)用UpdateWindow(),發(fā)出WM_PAINT消息;,5.回到WinMain中,調(diào)用pApp-Run,進入消息循環(huán),通過API函數(shù)GetMessage()獲得消息,TranslateMessage()處理消息,DispatchMessage()派送消息到CWnd:DefWindowProc() ,DefWindowProc()按照消息映射表的定義將消息分發(fā)到各相應(yīng)

15、消息處理函數(shù); 如消息隊列為空,則Run調(diào)用CWinApp:OnIdle()進行空閑處理,重載OnIdle()可以去處理后臺程序(低優(yōu)先級);,6.若用戶選擇菜單File/Close,則程序收到WM_COLSE消息,調(diào)用:DestroyWindow()發(fā)出WM_DESTROY消息,然后調(diào)PostQuitMessage() ,發(fā)出WM_QUIT消息,此時Run會結(jié)束其內(nèi)部消息循環(huán),調(diào)用ExitInstance() ;,7.最后,返回WinMain() ,執(zhí)行WinTerm() ,結(jié)束程序運行。,幾點解釋:,(1).每個MFC應(yīng)用都有stdafx.h頭文件,由應(yīng)用程序向?qū)ё詣由桑?(2).每個M

16、FC應(yīng)用都應(yīng)包含頭文件afxwin.h,其內(nèi)部又包含了其他頭文件。,(3).每一個MFC應(yīng)用程序都包含唯一的CWinApp派生類對象,代表應(yīng)用程序本身。,(4).MFC應(yīng)用程序中看不到WinMain()入口函數(shù),它被 封裝在應(yīng)用程序框架里,運行時自動調(diào)用;,3.2.2.MFC消息映射,消息映射(Message Map)機制: 消息映射機制規(guī)定每個要響應(yīng)消息的類定義自己的消息映射表,將消息與處理消息的函數(shù)聯(lián)系在一起;當(dāng)事件發(fā)生產(chǎn)生消息時,在程序中各個類的消息映射表中查找,當(dāng)找到消息處理函數(shù)時,便將消息送至對應(yīng)的消息處理函數(shù)進行處理。每個從CCmdTarget所派生的類都可以接收消息,都可以定義自

17、己的消息映射表Message Map。,消息映射表:,1.消息 消息是Windows用來通知MFC應(yīng)用程序事件發(fā)生的主要方式,應(yīng)用程序的行為取決于對消息的響應(yīng)方式。 MFC把消息分為三大類: (1).標準Windows消息(窗口消息)(WM_XXX), (2).命令消息(WM_COMMAND), (3).控件通知消息。,2.消息映射 消息映射將消息與應(yīng)用程序提供的處理該消息的成員函數(shù)聯(lián)系在一起,一組消息映射構(gòu)成消息映射表。 消息映射表由BEGIN_MESSAGE_MAP和END_MESSAGE_MAP 這一對宏作開始和結(jié)束,中間是若干消息映射入口 每一個入口由特定的消息宏ON_XXX組成,將一

18、個消息與與之對應(yīng)的處理函數(shù)聯(lián)系在一起。,定義和使用消息映射表的步驟:, 在頭文件的類聲明中添加DECLARE_MESSAGE_MAP宏聲明消息映射;例如, 在類的定義文件(.cpp)定義消息映射表,方法是在 文件的開始處添加BEIGN_MESSAGE_MAP和END_MESSAGE_MAP 這一對宏,在它們之間放置消息映射宏,定義并初始化消息映射表,在消息與處理消息的函數(shù)之間建立聯(lián)系;例如, 在類的定義文件(.cpp)中添加消息處理函數(shù)。例如,消息宏: (1).對標準Windows消息(窗口消息)的響應(yīng),消息宏ON_WM_XXX定義對標準Windows消息WM_XXX的響應(yīng),所有派生自CWnd

19、的類均可響應(yīng)這類消息,系統(tǒng)默認的響應(yīng)函數(shù)為OnXxx,對應(yīng)關(guān)系見下面的表3.3:,由于有系統(tǒng)默認的消息和處理函數(shù),在消息映射表中只寫宏名,如: ON_WM_CREATE(),(2).對命令消息的的響應(yīng) 。,ON_COMMAND宏定義對命令消息的響應(yīng),格式為 ON_COMMAND(命令I(lǐng)D,響應(yīng)函數(shù)) 舉例如下: ON_COMMAND ( IDM_ABOUT, OnAbout ) /表示IDM_ABOUT消息由OnAbout()響應(yīng) ON_COMMAND ( IDM_FILENEW, OnFileNew) ON_COMMAND ( IDM_FILEOPEN, OnFileOpen) 所有由用戶定

20、義的命令消息也由ON_COMMAND定義 消息映射關(guān)系。,(3).對控件消息的響應(yīng),控件消息由按鈕(BN_)、編輯框(EN_)、組合框(CBN_)、列表框(LBN_)等產(chǎn)生,在消息名前加上ON_即構(gòu)成宏名, 舉例如下: ON_BN_CLICKED (按鈕ID,響應(yīng)函數(shù)) ON_CBN_DBCLK (組合框ID,響應(yīng)函數(shù)) ON_EN_SETFOCUS (編輯框ID,響應(yīng)函數(shù)) ON_LBN_DBCLK (列表框ID,響應(yīng)函數(shù)) 分別表示選擇各個控件后,產(chǎn)生的消息由其后面定義 的函數(shù)進行處理。,3.消息處理 消息一般由應(yīng)用程序中對象的成員函數(shù)來響應(yīng)。當(dāng)某個事件發(fā)生后,系統(tǒng)向應(yīng)用程序消息隊列放入一

21、個消息,CWinApp對象取得消息并按照消息映射表的定義將消息派送到某個類的相應(yīng)的消息處理函數(shù)進行處理。 使用ClassWizard(見第五章菜單中View菜單介紹)定義消息映射關(guān)系,添加消息處理函數(shù),系統(tǒng)會自動生成函數(shù)原型和函數(shù)框架,開發(fā)人員只要添加函數(shù)體代碼,可以避免一些常見錯誤的產(chǎn)生。,程序中類響應(yīng)windows消息的優(yōu)先順序: 取決于消息傳遞的順序。 對于標準Windows消息(窗口消息),由產(chǎn)生這些消息的對象響應(yīng),如窗口的創(chuàng)建WM_CREATE,窗口的移動WM_MOVE,由產(chǎn)生消息的窗口類響應(yīng)。如果找不到相應(yīng)的處理函數(shù),則將消息傳遞到其父類,一般情況都有缺省的響應(yīng)函數(shù); 對于命令消息

22、WM_COMMAND,可由擁有菜單資源的所有類來處理,傳遞的順序是視圖類、文檔類、文檔模板類、框架類、應(yīng)用程序類,即這些類處理命令消息的優(yōu)先順序。 詳見第2章。,例如,當(dāng)用戶在視圖窗口中按下鼠標左鍵時,Windows發(fā)送WM_LBUTTONDOWN消息到應(yīng)用程序,假設(shè)視圖類需要響應(yīng)這些消息,在類的頭文件(.h)中有函數(shù)聲明和消息映射表的聲明: Class CMyView: public CView afx_msg void OnLButtonDown(UINT nFlags,CPoint point); /函數(shù)原型聲明 DECLARE_MESSAGE_MAP() /消息映射表聲明 返回,afx

23、_msg標識消息映射函數(shù),所有由ClassWizard生成的消息處理函數(shù)原型說明前都有這一標識。,注,視圖類的定義文件(.cpp)中必須有消息映射定義: BEIGN_MESSAGE_MAP(CMyView,CView) /消息映射表定義 ON_WM_LBUTTONDOWN() /函數(shù)名為OnLButtonDown /其它消息映射入口 END_MESSAGE_MAP() 以及對應(yīng)的消息響應(yīng)函數(shù)定義: void CMyView:OnLButtonDown(UINT nFlags, CPoint point) /處理消息的操作代碼,程序中具體實現(xiàn) 返回,將CMyView的基類CView也包含進去,當(dāng)

24、在派生類中沒找到處理函數(shù)時,允許在基類中繼續(xù)查找。,注,3.2.3.文檔/視圖結(jié)構(gòu),1.文檔類 在基于文檔/視圖結(jié)構(gòu)的應(yīng)用程序中,CDocument的派生對象負責(zé)讀入、保存和管理應(yīng)用程序的數(shù)據(jù)。每個文檔類可能與多個視圖類關(guān)聯(lián),而每個視圖包含一個指向與其相關(guān)的文檔的指針。 文檔類允許向其中增加數(shù)據(jù)成員,應(yīng)用程序的數(shù)據(jù)可以是任何類型的,或者是任何自定義的數(shù)據(jù)結(jié)構(gòu),如結(jié)構(gòu)體,類或鏈表等。,3.2.3.文檔/視圖結(jié)構(gòu),文檔類的常用成員函數(shù)(帶的表示是可重定義的虛函數(shù)),表3.4,2.視圖類,視圖類對象代表了應(yīng)用程序的窗口客戶區(qū),是文檔信息的一個顯示窗口(視口),它同時也是用戶與程序之間信息交互的橋梁,

25、用戶對數(shù)據(jù)的編輯和修改需要通過鍵盤或鼠標進行,這些消息都由視圖類接受后再反映到文檔類。,視圖類的派生關(guān)系:,圖3.5,CView類提供了向視圖或打印機進行輸出的基本框架,決定了視圖的基本特性,派生的視圖類可以重載基類的函數(shù),或增加新的函數(shù)以決定特定視圖的特性。 CView的派生類可以多種方式顯示文檔類的信息,每個視圖類根據(jù)顯示的方式各自定義其顯示代碼。 MFC提供了一系列這樣的類,如 CTreeView 樹型視圖 CListView 列表型視圖 CFormView 顯示基于對話框模板的視圖CScrollView 帶滾動條的視圖。,1)視圖類實現(xiàn)特定視圖的特性的虛函數(shù),表3.5,CEx3_1Do

26、c* pDoc = GetDocument(); 通過GetDocument獲得與視圖關(guān)聯(lián)的文檔類指針,通過指針pDoc訪問文檔類的數(shù)據(jù)成員和函數(shù)成員,在視圖(窗口)中顯示文檔對象,當(dāng)用戶通過視圖改變文檔數(shù)據(jù)時,可設(shè)置自動更新文檔內(nèi)容。 文檔/視圖結(jié)構(gòu)已經(jīng)把應(yīng)用程序所需要的數(shù)據(jù)處理與顯示(虛函數(shù))的框架構(gòu)造好,程序設(shè)計人員只需要將具體應(yīng)用的數(shù)據(jù)添加到文檔類,并根據(jù)數(shù)據(jù)類型在視圖類的虛函數(shù)OnDraw()中完成數(shù)據(jù)的顯示。,2) 視圖類的成員函數(shù)訪問與其關(guān)聯(lián)的文檔類的方式,3.文檔模板類,CDocTemplate類將框架、視圖、文檔對象及應(yīng)用 程序的資源捆綁在一起。應(yīng)用程序每打開一個文件,至少創(chuàng)

27、建一個文檔對象、一個視圖對象和一個框架窗口,而文檔模板對象負責(zé)管理所有這些對象,并將各種相關(guān)資源與之聯(lián)系在一起。 在大多數(shù)情況下,程序不需要對這個類進行修改。,對于SDI應(yīng)用,使用CSingleDocTemplate文檔模板。 對于MDI應(yīng)用,使用CMultiDocTemplate文檔模板。MDI允許有多個文檔模板,將不同文檔-視圖類聯(lián)系在一起,實現(xiàn)不同文檔視圖顯示關(guān)系。,4.文檔/視圖結(jié)構(gòu)應(yīng)用程序創(chuàng)建過程,使用AppWzard,根據(jù)實際需要,選擇創(chuàng)建合適的應(yīng)用程序框架(是否使用文檔/視圖結(jié)構(gòu),使用SDI或MDI等) 在文檔類中添加程序所處理的數(shù)據(jù),作為文檔類數(shù)據(jù)成員; 在視圖類中取得文檔數(shù)據(jù)

28、,以合適的方式在窗口中顯示出來,5.應(yīng)用實例,例3_1:創(chuàng)建一個包含文檔/視圖結(jié)構(gòu)單文檔界面應(yīng)用的實例,為文檔類添加一個字符串?dāng)?shù)據(jù),在視圖窗口顯示出來。 步驟如下: (1).在File菜單中選擇New,如圖3.,在Project頁面選擇MFC AppWizard(exe),在Project name中輸入Ex3_1,并選擇合適的路徑按OK按鈕。,(2).在AppWizard Step 1中,如圖3.,選擇Single Document單 選按鈕,并選中Document/ View architechure Support復(fù)選框, 表示使用文檔/視圖結(jié)構(gòu),按Finish按鈕。顯示New Proj

29、ect Information信息框,顯示新創(chuàng)建的工程的有關(guān)信息按OK按鈕,這樣工程創(chuàng)建完畢。,圖3. New Project對話框,圖3. AppWizard Step1,在VC集成開發(fā)環(huán)境中看到,新工程生成了五個類,如圖3.在class view頁面上可看到這些類。 CAboutDlg 派生自CDialog,一個About對話框。 CEx3_1App 派生自CWinApp,其全局對象theApp 代表應(yīng)用程序本身。 CEx3_1Doc 派生自CDocument,文檔類。 CEx3_1View 派生自CView,視圖類。 CMainFrame 派生自 CFrameWnd,程序框架類。,文檔、

30、視圖及應(yīng)用程序類名都以工程名開頭,后接對應(yīng)的類型名,這有助于在程序中有多個文檔視圖類時區(qū)分主視圖與其它視圖,區(qū)分主文檔與其它文檔類。 應(yīng)用程序向?qū)ppWizard為每個類生成了一個頭文件和一個.cpp文件,還自動生成了stdafx.h和stdafx.cpp,圖3.,AppWizard還生成了缺省的用戶界面資源文件,在Resource view頁面顯示。,圖3. ClassView,圖3.FileView,(3).為文檔類增加數(shù)據(jù)成員。在編輯窗口打開文檔類的頭文件Ex3_1Doc.h,手工添加一個字符數(shù)組成員m_StrName;或在Workspace的ClassView頁面,右擊 CEx3_1

31、Doc類,在彈出式菜單中選擇Add Member Variables,在對話框中輸入變量類型和名稱。 class CEx3_1Doc : public CDocument /Ex3_1Doc.h / Attributes public: char m_StrName80; ;,在文檔類構(gòu)造函數(shù)中對新增加的變量進行初始化。 CEx3_1Doc:CEx3_1Doc() /Ex3_1Doc.cpp / TODO: add one-time construction code here strcpy(m_StrName,A Simple Document/View Application.); (4)

32、.顯示字符串.在CEx3_1View的OnDraw()函數(shù)顯示字符串。 void CEx3_1View:OnDraw(CDC* pDC) CEx3_1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here pDC-TextOut(0,0,pDoc-m_StrName); /Ex3_1View.cpp,圖3.10 例3.1第一步主界面,3.3.用戶界面資源的應(yīng)用,資源是windows應(yīng)用程序的一種特殊數(shù)據(jù),包括菜單、加速鍵、光標、位圖、圖標、對話框、字符串、工具欄、狀態(tài)欄等

33、,資源一般放在exe或DLL文件中。 當(dāng)windows將程序裝入內(nèi)存時,一般不將資源同時裝入,而是當(dāng)需要某個資源時才將相應(yīng)資源裝入。 資源定義在資源腳本(resource scirpt)文件中。 以.rc為文件擴展名,文件名與工程名相同。 資源腳本文件中定義了各種資源的相關(guān)數(shù)據(jù),Windows通過使用不同的資源標識符前綴來區(qū)分不同資源類型(如表3.所示),這樣做雖然不是必須的,但遵循這樣的規(guī)則 有利于提高程序的通用性和可讀性。,表3. 資源類型及其標示,資源標識前綴 IDM_ ID_ IDI_ IDB_ IDD_ IDR_ IDC_ IDS_,資源類型 菜單項ID 菜單命令I(lǐng)D 圖標ID 位圖

34、ID 對話框ID 菜單欄、工具欄、加速鍵 控件ID 字符串,返回,Visual C+ 6.0中提供了資源編輯器,對資源進行可視化編輯,并自動生成資源腳本文件;腳本文件可用文本編輯器進行編輯,但其可讀性較差,容易出錯,一般情況下盡量不要進行編輯。 用戶定義的資源標識符號常量定義在resource.h文件中。 本節(jié)為例題3_1添加一些內(nèi)容。,3.3.用戶界面資源的應(yīng)用,3.3.1.菜單,分類: 頂層菜單 : 一般位于應(yīng)用程序主窗口或頂層窗口 彈出式菜單: 選擇某個菜單項后彈出的子菜單,1.菜單的編輯,如果是AppWizard產(chǎn)生的程序,系統(tǒng)已為框架創(chuàng)建了一個標準的主菜單,包括文件、編輯、視圖、窗口

35、幫助等標準菜單,定義了各菜單項的ID及相應(yīng)的命令處理函數(shù)。在Resource View頁面,打開工程資源,選擇Menu,然后雙擊主菜單資源IDR_MAINFRAME標示,可打開菜單編輯器。,添加新的菜單資源,選擇Insert Resource菜單項,在Insert Resource對話框中,選擇Menu資源類型,單擊New按鈕,缺省新菜單名為IDR_MENU1。,a) 增加一個頂層菜單,在菜單屬性對話框中,選中Pop-up選項,可以定義一個頂層菜單,在Caption編輯框中輸入菜單名,菜單名即顯示在菜單上。若在菜單名的某個字符前加一個 /可以向數(shù)組中增加ID以增加狀態(tài)欄上顯示欄。,3.3.3

36、狀態(tài)欄,圖3.16 例3.1主界面,3.4.對話框的應(yīng)用,3.4.1 對話框的工作方式、種類和創(chuàng)建方法,1. 對話框在應(yīng)用程序中的工作方式,對話框是一個讀入或?qū)懗鰯?shù)據(jù)的圖形界面對象,由集成開發(fā)環(huán)境中的對話框模板提供,可以向模板添加各種控件(如按鈕,編輯框,單選復(fù)選按鈕等),構(gòu)成程序的對話框資源;,應(yīng)用程序要使用對話框還需定義一個CDialog派生類的對話框類與資源相連接,并在這個對話框類中定義一些成員變量與對話框中的控件相對應(yīng),提供對話框控件的缺省數(shù)據(jù)值;,程序運行時需要用到對話框時依據(jù)對話框資源激活對話框,接收用戶輸入后通過成員函數(shù)更新文檔類數(shù)據(jù)成員,如圖3.17示。,圖3.17對話框與文檔

37、的數(shù)據(jù)交換,構(gòu)造對話框并更新 文檔數(shù)據(jù),數(shù)據(jù)交換,對話框模板 controls,public: data members,文檔類: application datas,對話框類對象,2. 對話框的種類,Windows有兩種對話框,模態(tài)對話框和非模態(tài)對話框,構(gòu)造兩種對話框的大多數(shù)工作都相同,只是兩者的顯示和數(shù)據(jù)處理有些不同。,模態(tài)對話框(Modal Dialog Boxes)工作時使其父類窗口無效,直到對話框結(jié)束。也就是說,該對話框打開后, 程序等待用戶輸入,在關(guān)閉對話框后才執(zhí)行其它任務(wù)。 調(diào)用DoModal()函數(shù)可以顯示模態(tài)對話框。如: CMyDialog dlg; dlg.DoModal(

38、); DoModal返回用戶單擊的按鈕的ID值(如IDOK或IDCANCEL),單擊OK或CANCEL按鈕后,自動調(diào)用CDialog:EndDialog()關(guān)閉對話框。,非模態(tài)對話框( Modeless Dialog Boxes)在打開期間,允許用戶切換到程序其它部分,不一定要關(guān)閉對話框。如WinWord中的Find and Replace對話框。 對系統(tǒng)而言,一個非模態(tài)對話框相當(dāng)于另一個線程,可以說是執(zhí)行中的另外一個程序。調(diào)用Create函數(shù)創(chuàng)建并顯示非模態(tài)對話框: CMyDialog dlg; dlg.Create(); 用戶按下OK或CANCEL按鈕不會關(guān)閉對話框,可重定義OnOK和On

39、Cancel函數(shù),調(diào)用DestroyWindow關(guān)閉對話框(即后文建立對話框的方法是針對模態(tài)對話框的): void CMyDialog:OnOK() DestroyWindow(); void CMyDialog:OnCancel() DestroyWindow();,3. 對話框的創(chuàng)建與編輯,a)對話框的創(chuàng)建,選擇Insert|Resource.,在Insert Resource對話框中選擇Dialog類型,按New按鈕,打開對話框編輯器,缺省情況下,對話框模板提供了OK和Cancel兩個按鈕,同時打開了對話框工具欄和控件工具欄,如下圖。,圖3.18對話框模板及編輯工具,在對話框模板內(nèi)右擊鼠

40、標,在彈出的菜單中選擇Properties,打開Dialog Property對話框。,圖3.19對話框?qū)傩詫υ捒?b)控件屬性,將控件工具欄中的任一種控件拖至對話框模板中,在控件上右擊鼠標,選擇Properties打開控件屬性對話框,如圖3.20。這是為例3_1添加的輸入學(xué)生信息的對話框。 各種控件屬性對話框基本相似,在ID框中輸入標識控件的唯一ID值,在Caption中輸入控件上顯示的字符(Edit控件沒有這一屬性),Visible表示該控件在對話框創(chuàng)建時是否顯示,Group用來控制控件分組,Disabled使控件不可用,Tab stop表示是否用Tab鍵選擇控件。,圖3.20 控件屬性設(shè)

41、置對話框,c)控制Tab順序,當(dāng)打開對話框編輯器后,集成開發(fā)環(huán)境的菜單上多了一個Layout菜單,其中主要是對話框工具欄上顯示的一些命令,其中有一個命令Tab Order,定義當(dāng)用戶用Tab鍵移動輸入焦點時各控件接受焦點的順序。假如編輯一個如圖3.20的對話框,選擇Layout|Tab order,對話框編輯器顯示定義時的順序,這時用鼠標點擊各個控件,則Tab順序就定義為鼠標點擊的順序,如圖3.21所示。對于靜態(tài)文本框,由于不需要輸入焦點,就放在最后。,d)分組控制,VC提供了根據(jù)控件功能將控件進行分組的工具,使用戶更易于理解對話框的結(jié)構(gòu)。在分組框中使用最多的是單選按鈕(radio butto

42、ns),一組單選按鈕允許用戶在組內(nèi)多個相互排他的選項內(nèi)選擇一項。,圖3.21設(shè)置Tab Order,e)組合框Combo Box,將組合框拖至對話框中后,按向下箭頭,顯示運行時下拉組合框的大小,調(diào)整到合適大小。組合框的屬性對話框比其它控件多一個Data頁面,用于輸入組合框中的數(shù)據(jù)項,每一行是一項,輸完一項按Ctrl+Enter鍵換行。,f)列表框List Box,在對話框編輯器中只能設(shè)置列表框大小、位置和ID,數(shù)據(jù)的初始化需要通過編程實現(xiàn)。一般在擁有列表框控件的對話框的OnInitDialog函數(shù)中,調(diào)用CListBox:AddString(無序)或CListBox:InsertString(

43、有序)插入字符串。,g)測試對話框,當(dāng)所有控件都布置好并定義屬性后,可以選擇對話框工具欄上的測試按鈕,測試對話框工作情況,必要的話做適當(dāng)調(diào)整。,3.4.2 將對話框與程序連結(jié),1.對話框類及數(shù)據(jù)成員的定義,a)創(chuàng)建對話框類,對話框資源建立好后,在對話框中右擊鼠標,選擇ClassWizard菜單項,會出現(xiàn)提示框,說明新建的對話框資源是新資源,是否需要建立一個新類或選擇一個已存在的類。 若選擇新類,出現(xiàn)圖3.23示的New class對話框 。 選定后,在WorkSpace中可看到新增加的類,自動生成的StudentDlg.h頭文件和StudentDlg.cpp源文件。,圖3.23新建類對話框,b

44、)增加數(shù)據(jù)成員,要使對話框能與程序通訊,還需給對話框類增加數(shù)據(jù)成員,以保存各控件的初始值,并從控件讀取數(shù)據(jù)。 與控件對應(yīng)的數(shù)據(jù)成員可以是變量或控件類型,如表3.9所示。,表3.9對話框與控件對應(yīng)的變量或控件數(shù)據(jù)成員,在ClassWizard的Member Variables頁面,選擇對話框類,在Control IDs中列出了對話框中所有控件ID,如圖3.24,選擇某個ID,按Add Variable按鈕,彈出Add Member Variable對話框,可輸入成員名,在Category中選擇值(value)變量或控件(controls)類型,在Variable type列表框中,若是Value

45、類,選擇變量數(shù)據(jù)類型,若是Controls,選擇控件類,按OK,成員添加成功。 對學(xué)生信息輸入框的數(shù)據(jù)成員變量表如圖3.25。 數(shù)據(jù)成員定義后,在對話框第一次顯示時需對其初始化。有兩種初始化成員變量的方法:一是在對話框類的構(gòu)造函數(shù)中初始化,由ClassWizard自動生成;二是構(gòu)造對話框?qū)ο蠛筮M行初始化。為使用方便,對話框變量成員一般定義成public訪問權(quán)限,因此可以在使用對話框的地方初始化。,ClassWizard自動在構(gòu)造函數(shù)中初始化變量,代碼放在/AFX_ 和/AFX_括號中間,一般不需要對其改動。 CStudentDlg:CStudentDlg(CWnd* pParent /*=NU

46、LL*/):CDialog(CStudentDlg:IDD, pParent) /AFX_DATA_INIT(CStudentDlg) m_sDepart = _T(); m_dComputer = 0.0; m_dEnglish = 0.0; m_nID = 0; m_dMath = 0.0; m_sName = _T(); m_dPhysics = 0.0; m_nSex = -1; /AFX_DATA_INIT ,ClassWizard還為對話框生成了DDX(Dialog Data Exchange)函數(shù)成員DoDataExchange(),此函數(shù)不應(yīng)被顯式調(diào)用,而由UpdateData

47、()函數(shù)調(diào)用,它可以實現(xiàn)在對話框控件與對話框數(shù)據(jù)成員之間的雙向數(shù)據(jù)交換。 UpdateData(FALSE),將對話框?qū)ο蟮某蓡T變量值復(fù)制至對話框控件,用于向用戶顯示數(shù)據(jù)。 UpdateData(TRUE)將對話框控件中數(shù)據(jù)復(fù)制至對話框?qū)ο蟪蓡T變量,默認值是TRUE。 如果選擇對話框的OK按鈕關(guān)閉對話框,會自動調(diào)用UpdateData()。 對分組的單選按鈕,在ClassWizard中只出現(xiàn)組內(nèi)第一個單選按鈕的ID。為區(qū)分不同的按鈕,需增加一個成員變量,其類型只能是int。選中第一個按鈕,其值為0,選中第二個按鈕,其值為1,依此類推。,圖3.24為對話框添加數(shù)據(jù)成員,圖3.25對話框的變量和控

48、件數(shù)據(jù)成員,2.對話框的顯示,模態(tài)對話框 調(diào)用DoModal()函數(shù)顯示對話框, 并做相應(yīng)數(shù)據(jù)處理。 按OK或Cancel按鈕關(guān)閉對話框, 非模態(tài)對話框 調(diào)用Create()函數(shù)創(chuàng)建并顯示對話框, 調(diào)用DestroyWindow()函數(shù)關(guān)閉 對話框。 模態(tài)對話框和非模態(tài)對話框在創(chuàng)建資源時是一致的,僅在顯示對話框調(diào)用的函數(shù)不一樣。 對話框與文檔數(shù)據(jù)的交互是雙向的。參見下例:,定義CStudent類,其數(shù)據(jù)成員與學(xué)生信息輸入對話框內(nèi)容對應(yīng);其成員函數(shù)SetStu()以對話框輸入的內(nèi)容為數(shù)據(jù)成員賦值。在文檔類中定義CStudent對象stu。視圖類響應(yīng)輸入命令(如增加一個菜單命令I(lǐng)nput,響應(yīng)函數(shù)

49、為OnInput(),為輸入學(xué)生信息打開對話框,則下面代碼為對話框按OK按鈕后,用對話框成員變量更新文檔數(shù)據(jù)。 void CEx3_1View:OnInput() / TODO: Add your command handler code here CEx3_1Doc* pDoc = GetDocument(); CStudentDlg dlg;/構(gòu)造對話框?qū)ο?if(dlg.DoModal()=IDOK) /顯示對話框并選擇OK按鈕后 pDoc-stu.SetStu(dlg); /將對話框數(shù)據(jù)賦給文檔數(shù)據(jù)成員 ,也可以通過菜單命令,調(diào)用函數(shù)ShowData(),用對話框輸出文檔數(shù)據(jù)。方法是先

50、構(gòu)造對話框變量,然后用文檔數(shù)據(jù)為對話框數(shù)據(jù)成員賦值,再顯示對話框,代碼如下: void CEx3_1View:ShowData() / TODO: Add your command handler code here CEx3_1Doc* pDoc = GetDocument(); CStudentDlg dlg; /構(gòu)造對話框?qū)ο?dlg.Setdata(Doc-stu); /將文檔數(shù)據(jù)成員賦給對話框數(shù)據(jù)成員 dlg.DoModal(); /顯示對話框,控件顯示文檔數(shù)據(jù) ,3.為控件添加或修改消息響應(yīng)函數(shù),打開ClassWizard,在Message Map頁面,可以為控件添加響應(yīng)函數(shù)。如圖

51、3.26。為OK按鈕添加默認的響應(yīng)函數(shù)OnOK()。 Class Wizard在類的聲明中添加函數(shù)聲明,并在類的cpp文件中添加空的函數(shù)體,由程序設(shè)計人員完成函數(shù)代碼。這樣單擊OK按鈕,就會調(diào)用OnOK函數(shù)。 void CStudentDlg:OnOK() / TODO: Add extra validation here UpdateData(); /首先使數(shù)據(jù)傳送至對話框成員變量 CDialog:OnOK(); /調(diào)用基類OnOK并關(guān)閉對話框 ,圖3.26為控件添加響應(yīng)函數(shù),圖3.27 例3.1 新主界面,3.5.基于對話框的應(yīng)用程序設(shè)計,AppWizard提供了基于對話框(Dialog

52、based)的應(yīng)用程序框架,程序可以簡單到只有CWinApp派生類和一個對話框類,對話框就是程序框架,負責(zé)數(shù)據(jù)輸入輸出和存儲,以及消息處理;對話框可以有最小化按鈕,甚至可以連接一個菜單。,基于對話框的應(yīng)用程序結(jié)構(gòu)簡單,只要正確選擇控件及定義成員變量,設(shè)計正確的算法。 適合開發(fā)數(shù)據(jù)不多,功能簡單的程序。,【例3.2】基于對話框的應(yīng)用程序,在主框架窗口對話框上有三個組合框,分別選擇某年某月某日,按下”Show Weekday”按鈕,在Weekday列表框中顯示這天是星期幾。,步驟如下: 1.創(chuàng)建Dialog based工程Ex3_2 工程創(chuàng)建完畢后,除了CAboutDlg,AppWizard還生成

53、了兩個類: CEx3_2App 代表應(yīng)用程序的CWinApp派生類; CEx3_2Dlg 以IDD_EX3_2_DIALOG為模板的對話框,是程序主框架。 2.編輯對話框資源 為IDD_EX3_2_DIALOG對話框模板添加控件,如圖3.28所示。對話框控件ID及添加的相應(yīng)數(shù)據(jù)成員見表3.10。 組合框數(shù)據(jù)在Combo box properties對話框的Data選項卡輸入,輸入數(shù)據(jù)為Year 19902010, Month 112, Date 131。,圖3.28對話框模板,表3.10 例Ex3_2對話框控件及變量定義,3.定義列表框 數(shù)據(jù)不能在控件屬性對話框中輸入,必須為列表框定義一個CL

54、istBox控件類型變量,在對話框的OnInitDialog()函數(shù)中為其插入內(nèi)容。,BOOL CEx3_2Dlg:OnInitDialog() CDialog:OnInitDialog(); m_listWeekday.InsertString(0,Sunday); /向列表框插入字符串 m_listWeekday.InsertString(1,Monday); /字符串編號必須從0開始,并應(yīng)該順序排列 m_listWeekday.InsertString(2,Tuesday); m_listWeekday.InsertString(3,Wednesday); m_listWeekday.I

55、nsertString(4,Thursday); m_listWeekday.InsertString(5,Friday); m_listWeekday.InsertString(6,Saturday); return TRUE; ,4. 程序涉及的算法 要計算某年某月某日是星期幾,應(yīng)有一個基準日,然后算出某日離基準日的天數(shù),即可算出星期幾。1990年1月1日是星期一,以這天為基準。 為計算閏年與非閏年天數(shù)差異,在Ex3_2Dlg.cpp文件中定義一個全局二維數(shù)組: char daytab213 = 0,31,28,31,30,31,30,31,31,30,31,30,31, 0,31,29,

56、31,30,31,30,31,31,30,31,30,31;,為對話框添加兩個成員函數(shù),其一響應(yīng)按鈕Show Weekday命令,通過ClassWizard對話框添加。另一為計算指定日期為當(dāng)年的第幾天,在Workspace中右擊對話框類名,選擇Add member functions進行添加。 int CEx3_2Dlg:DayOfYear(int y, int m, int d) /計算某日在當(dāng)年的第幾天 int i,leap; leap = y%4 =0 ,void CEx3_2Dlg:OnShow() UpdateData(); /讀入對話框控件數(shù)據(jù),接受輸入 int year,mont

57、h,date,days=0, i,weekday; year = atoi(m_csYear); /將年月日字符串轉(zhuǎn)換為整數(shù)便于計算 month = atoi(m_csMonth); date = atoi(m_csDate); for(i = 1990; i year; i+) /for循環(huán)計算9093這四年整的天數(shù) if(i%4=0/使對話框無效,重畫 ,3.6.文本和圖形輸出,Windows設(shè)備描述表DC(device contexts),是對各種不同設(shè)備的抽象,應(yīng)用程序只要向DC輸出,由DC負責(zé)處理不同設(shè)備的差異。,DC是一個數(shù)據(jù)結(jié)構(gòu),描述了圖形設(shè)備接口GDI進行輸出所需要的信息,包括

58、顏色,填充方式,畫筆寬度等。在Windows中,DC允許應(yīng)用程序使用輸出設(shè)備,DC在應(yīng)用程序、設(shè)備驅(qū)動程序、與輸出設(shè)備之間建立聯(lián)系,并提供繪圖信息。,在MFC中,CDC類封裝了設(shè)備描述表DC,該類的核心是 m_hDC,代表一個指向窗口DC的句柄。,1.CDC類及其派生類,CDC類派生自CObject,它具有CObject類的共同特性,如可以動態(tài)創(chuàng)建,可進行序列化操作。,(a).設(shè)置顏色,windows使用一個32位無符號整型值來表示圖形和文本的顏色,其數(shù)據(jù)類型為COLORREF,它包含4個字節(jié),第一字節(jié)未使用,不要改變其值;后面三個字節(jié)分別表示紅、綠、藍三種基本色的成分,每一種顏色用一個0-255之間的數(shù)字表示。,設(shè)備描述表最常見的使用是在視圖類的OnDraw函數(shù)中進行圖形和文本輸出,2.CDC類的使用,宏RGB定義顏色值,宏 RGB 定義一個顏色的三種基本色成分,返回COLORREF值 GetRValue 返回一個CO

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論