MFC原理與方法_第1頁
MFC原理與方法_第2頁
MFC原理與方法_第3頁
MFC原理與方法_第4頁
MFC原理與方法_第5頁
已閱讀5頁,還剩124頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、MFC微軟基礎(chǔ)類,MFC(Microsoft Foundation Class)微軟基礎(chǔ)類是一個由Microsoft公司設(shè)計的類庫。 MFC框架定義了應(yīng)用程序的輪廓,并提供了用戶接口的標準實現(xiàn)方法,程序員要做的就是通過接口把具體應(yīng)用程序特有的東西填入這個輪廓。 MFC的目的是讓應(yīng)用程序員在應(yīng)用程序框架的基礎(chǔ)上建立Windows下的應(yīng)用程序,這種方法相對于SDK來說更為簡單。 采用MFC方式編程提高了Windows應(yīng)用程序的開發(fā)效率。 認識MFC只是一個過程、一個手段,最終目的是為了良好并熟練地運用MFC。,采用MFC編程的優(yōu)點,使用標準化的程序代碼結(jié)構(gòu),有利于程序員之間的交流。 Visual

2、C+為MFC提供了大量的工具支持,提高了編程效率。如利用MFC AppWizard創(chuàng)建MFC應(yīng)用程序框架,利用ClassWizard方便地對Windows消息進行管理。 MFC應(yīng)用程序的效率較高,只比傳統(tǒng)的Windows C程序低5%左右。并且,在MFC應(yīng)用程序中還允許混合使用傳統(tǒng)的Windows API函數(shù)。 其它優(yōu)勢:完全支持Windows所有的函數(shù)、控件、消息、菜單及對話框;具有良好的穩(wěn)定性和可移植性,更符合微軟的風(fēng)格等。,MFC體系結(jié)構(gòu),MFC主要組成部分:類、宏和全局函數(shù)。 類是MFC中最主要的內(nèi)容。MFC類是以層次結(jié)構(gòu)方式組織起來的。MFC中的類分成兩部分,除了一些輔助類,大多數(shù)的

3、MFC類是直接或間接從根類CObject派生而來。 幾乎每一個派生層次都與一具體的Windows實例相對應(yīng),如文檔類、窗口類和視圖類等。 MFC宏主要功能:消息映射、運行時對象類型服務(wù)、診斷服務(wù)、異常處理。 MFC約定:全局函數(shù)以“Afx”為前綴,全局變量以“afx”為前綴。,學(xué)習(xí)MFC的方法,首先要對Windows編程概念和API函數(shù)有一定的了解,如Windows API有哪些功能和哪些常用的數(shù)據(jù)結(jié)構(gòu)等。 學(xué)會抽象地把握問題,不求甚解,不要一開始學(xué)習(xí)Visual C+就試圖了解整個MFC類庫。從理解和使用兩個方面學(xué)習(xí)MFC,理解MFC應(yīng)用程序的框架結(jié)構(gòu)。 先大體上了解MFC的概念、組成和基本

4、約定,從簡單的類入手,結(jié)合程序設(shè)計,由淺入深,循序漸進、日積月累。 編程時如果MFC某個類能完成所需要的功能,可以直接調(diào)用已有類的方法(成員函數(shù))。否則,可以利用面向?qū)ο蠹夹g(shù)中的“繼承”方法對MFC類的行為進行擴充和修改,從MFC中已有的類派生出自己需要的類。 學(xué)習(xí)MFC,另一點就是不要過分依賴于向?qū)В╓izard)工具。向?qū)茏鲈S多工作,但同時掩飾了太多的細節(jié)。,MFC應(yīng)用程序生成,MFC中的常用類,CObject、CCmdTarget、CWinThread、CWinApp、CWnd、CFrameWnd、CDialog、CView、CStatic、CButton、CListBox、CComb

5、oBox、CEdit、CScrollBar MFC 中的大部分類都是從基類 CObject 中繼承的,該類包含大部分 MFC 類所通用的數(shù)據(jù)成員和成員函數(shù); CWinApp 類是在建立應(yīng)用程序時需要用到的,并且在任何程序中都只用一次; CWnd 類匯集了 Windows 中的所有通用特性、對話框和控制。 CFrameWnd 類是從 CWnd 中繼承的,并實現(xiàn)了標準的框架應(yīng)用程序;,CDialog 可分別處理無模式和有模式兩種類型的對話框。 CView 用于讓用戶通過窗口來訪問文檔。,在MFC應(yīng)用程序的CWinApp派生類對象theApp是一個全局變量,代表了應(yīng)用程序運行的主線程。它在程序整個運

6、行期間都存在,它的銷毀意味著運行程序的消亡。 MFC應(yīng)用程序啟動時,首先創(chuàng)建應(yīng)用程序?qū)ο髏heApp,這時將自動調(diào)用應(yīng)用程序類的構(gòu)造函數(shù)初始化對象theApp,然后由應(yīng)用程序框架調(diào)用MFC提供的AfxWinMain()主函數(shù)。 AfxWinMain()主函數(shù)首先通過調(diào)用全局函數(shù)AfxGetApp()獲取應(yīng)用程序?qū)ο髏heApp的指針pApp,然后通過pApp調(diào)用應(yīng)用程序?qū)ο蟮挠嘘P(guān)成員函數(shù),完成程序的初始化和啟動工作,最后調(diào)用成員函數(shù)Run(),進入消息循環(huán)。 程序運行后將收到WM_PAINT消息,調(diào)用OnPaint()函數(shù)繪制客戶區(qū)窗口。如果Run()收到WM_QUIT消息,則結(jié)束消息循環(huán),然

7、后調(diào)用函數(shù)ExitInstance(),結(jié)束程序運行。,MFC應(yīng)用程序的生與死,hello程序流程,MFC應(yīng)用程序?qū)ο笾g的關(guān)系,MFC應(yīng)用程序運行后各函數(shù)的調(diào)用關(guān)系,InitInstance()函數(shù)是派生類唯一需要重載的函數(shù),它負責(zé)應(yīng)用程序的初始化。,CWinApp類,CWinApp 類提供了用戶與 Windows 應(yīng)用程序之間進行交流的接口。在生成類的對象后,對象自動建立與 Windows 系統(tǒng)的連接、接收 Windows 傳送的消息,并交給程序中相應(yīng)的對象去處理,這就免去了程序員的許多工作,使得開發(fā) C+的 Windows 程序變得簡單方便。 CWinApp類的對象theApp將自動創(chuàng)建

8、一個主線程,主線程中有一個循環(huán)體,用來不斷的從應(yīng)用消息隊列中提取消息,并發(fā)送回操作系統(tǒng),讓操作系統(tǒng)調(diào)用窗口過程函數(shù),實現(xiàn)消息響應(yīng)。CWinApp類通過消息映射宏的方式,方便開發(fā)人員完成消息與響應(yīng)函數(shù)之間的對應(yīng)關(guān)系,大大簡化了編程難度與復(fù)雜度。,CMainFrame類,類 CMainFrame 是由 MFC 中的 CFrameWnd 派生的,所以它也是一個框架窗口。CMainFrame 是類 CXXView 的父類,即 CXXView 類的對象顯示在主框架窗口的客戶區(qū)中。在類 CMainFrame 中,系統(tǒng)已經(jīng)從類 CFrameWnd 中繼承了處理窗口的一般事件的 Windows消息,如改變窗口

9、的大小、窗口最小化等的成員函數(shù),因此編程時程序員不必關(guān)心此類消息的處理,從而減輕了程序員的負擔(dān)。當(dāng)然,如果確實需要重新編寫此類消息的成員函數(shù),則需要對原有的成員函數(shù)進行重載。,當(dāng)程序的一個實例被運行時,系統(tǒng)將根據(jù)前面在 CWinApp 類中介紹的文檔模板對象自動生成類 CMainFrame、CXXView、CXXDoc 的對象,而不需要程序員主動地去創(chuàng)建這些類的對象。,類 CXXView 與 CXXDoc,這兩個類是密切相關(guān)的,文檔是由文檔模板對象生成的,并由應(yīng)用程序?qū)ο蠊芾?,而用戶則是通過與文檔相聯(lián)系的視窗對象來存儲、管理應(yīng)用程序中的數(shù)據(jù),用戶與文檔之間的交互是通過與文檔相關(guān)聯(lián)的視窗對象進行

10、的。 生成一個新的文檔時,MFC 程序同時生成一個框架窗口,并且在框架窗口的客戶區(qū)中生成一個視窗對象作為框架窗口的子窗口,這個子窗口以可視化的方式表現(xiàn)文檔中的內(nèi)容。視窗的重要功能就是負責(zé)處理用戶的鼠標、鍵盤等操作,通過對視窗對象的處理達到處理文檔對象的目的。,MFC通用控件類和窗口類,繪圖類,CClientDC 類:一般用來方便地創(chuàng)建和銷毀一個設(shè)備環(huán)境。CClientDC 通常在堆棧上創(chuàng)建。析構(gòu)函數(shù)自動調(diào)用ReleaseDC(),不會導(dǎo)致內(nèi)存資源泄漏. CWindowDC 類:與 CClientDC 類相似,但它的工作范圍是窗口的非客戶區(qū)。 CPaintDC 類:僅允許繪制無效的窗口客戶區(qū)而不

11、是繪制整個窗口, CWnd:BeginPaint()與CWnd:EndPaint()配對使用; CMetaFileDC 類:用于創(chuàng)建元文件,元文件是一種磁盤文件,它包含了所有的繪圖行為以及繪制圖像所需要的繪圖模式。,常用的MFC文件和庫文件,進入下一節(jié),MFC消息管理,MFC應(yīng)用程序消息處理的方式與SDK應(yīng)用程序有所不同。MFC應(yīng)用程序框架截取了Windows向應(yīng)用程序發(fā)出的消息,再確定將消息發(fā)送給哪一個對象,可以根據(jù)需要利用函數(shù)重載對消息進行處理,但不需要處理的消息將由應(yīng)用程序框架自動處理。 消息管理包括消息的發(fā)送和處理。對于消息發(fā)送,MFC提供了類似于API函數(shù)功能的消息發(fā)送函數(shù),而MFC

12、消息處理的內(nèi)部機制則相對復(fù)雜一些。從編程的角度出發(fā),我們只需了解其大致的原理。,MFC的消息分類,標準Windows消息:以WM_前綴(但不包括WM_COMMAND)開始的消息,包括鼠標消息、鍵盤消息和窗口消息,如WM_MOVE 、WM_PAINT等。 控件通知(Control Notification)消息:對控件操作引起的消息,是控件和子窗口向其父窗口發(fā)出的WM_COMMAND通知消息。例如,當(dāng)用戶修改了編輯控件中的文本后,編輯控件向其父窗口發(fā)送WM_COMMAND通知消息。 命令(Command)消息:由菜單項、工具欄按鈕、快捷鍵等用戶界面對象發(fā)出的WM_COMMAND消息。命令消息與其

13、它消息不同,它可被更廣泛的的對象如文檔、文檔模板、應(yīng)用程序?qū)ο?、窗口和視圖等處理。 自定義消息,MFC消息映射機制,MFC采用消息映射(Message Map)機制取代C/C+語言中的switch-case結(jié)構(gòu)來處理消息。 MFC消息映射機制包括一組消息映射宏,一條消息映射宏把一個Windows消息和其消息處理函數(shù)聯(lián)結(jié)起來。 在類定義的結(jié)尾用DECLARE_MESSAGE_MAP()宏來聲明使用消息映射。 在類的實現(xiàn)源文件中用BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()宏來定義消息映射。 ON_COMMAND宏:消息映射宏的第一個參數(shù)為消息ID,第二個參數(shù)為消息處

14、理函數(shù)。 如ON_COMMAND(ID_FILE_NEW,CWinApp:OnFile New)。 MFC 使用ClassWizard幫助實現(xiàn)消息映射功能。,例子: 在 AppWizard產(chǎn)生的應(yīng)用程序類的源碼中,應(yīng)用程序類的定義(頭文件)包含了類似如下的代碼: /AFX_MSG(CTttApp) afx_msg void OnAppAbout(); /AFX_MSG DECLARE_MESSAGE_MAP() 應(yīng)用程序類的實現(xiàn)文件中包含了類似如下的代碼: BEGIN_MESSAGE_MAP(CTApp, CWinApp) /AFX_MSG_MAP(CTttApp) ON_COMMAND(ID

15、_APP_ABOUT, OnAppAbout) /AFX_MSG_MAP END_MESSAGE_MAP() 頭文件里是消息映射和消息處理函數(shù)的聲明,實現(xiàn)文件里是消息映射的實現(xiàn)和消息處理函數(shù)的實現(xiàn)。它表示讓應(yīng)用程序?qū)ο筇幚砻钕?ID_APP_ABOUT,消息處理函數(shù)是OnAppAbout。,MFC應(yīng)用程序MESSAGE_MAP消息映射形式,BEGIN_MESSAGE_MAP(theclass, baseclass) /AFX_MSG_MAP(theclass) ON_ . . . . . . / MFC預(yù)定義的消息映射宏 ON_MESSAGE(message , memberFxn) /

16、用戶自定義的消息映射宏 . . . . . . /AFX_MSG_MAP END_MESSAGE_MAP(),注意:特殊注解“/AFX_MSG_MAP”是ClassWizard類向?qū)в糜诰S護消息映射宏的標記,用戶不要刪除注解輕易修改注解內(nèi)的代碼。,例 利用ClassWizard為框架類添加消息WM_CLOSE、WM_DESTROY及菜單項“Edit|Copy”的消息處理函數(shù),分析ClassWizard完成了哪些工作。,啟動ClassWizard,添加要求的三個消息處理函數(shù),ClassWizard將在類的實現(xiàn)文件中添加三個消息映射宏和消息處理函數(shù)。消息映射宏如下: BEGIN_MESSAGE_M

17、AP(CMainFrame, CFrameWnd) /AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() / 由MFC AppWizard程序向?qū)ё詣由傻南⒂成?ON_WM_CLOSE() / 由ClassWizard類向?qū)砑?ON_WM_DESTROY() ON_COMMAND(ID_EDIT_COPY, OnEditCopy) /AFX_MSG_MAP END_MESSAGE_MAP(),ClassWizard在類的定義中聲明了消息處理函數(shù),class CMainFrame : CFrameWnd public: CMainFrame(); protecte

18、d: /AFX_MSG(CMainFrame) / 聲明消息處理函數(shù)原形 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); / 由程序向?qū)ё詣由?afx_msg void OnClose(); / 由ClassWizard類向?qū)砑?afx_msg void OnDestroy(); afx_msg void OnEditCopy(); /AFX_MSG DECLARE_MESSAGE_MAP() / 聲明使用消息映射宏 ;,消息的發(fā)送,發(fā)送消息到一個窗口可以采用傳送(Send)或寄送(Post)方式,這兩種方式之間的主要區(qū)別是消息被接

19、收對象收到后是否立即被處理。Windows提供了三個API函數(shù)用于消息的發(fā)送。 函數(shù)SendMessage()用于向一個或多個窗口傳送消息,該函數(shù)將調(diào)用目標窗口的窗口函數(shù),直到目標窗口處理完收到的消息,該函數(shù)才返回。 函數(shù)PostMessage()用于向一個或多個窗口寄送消息,它把消息放在指定窗口創(chuàng)建的線程的消息隊列中,然后不等消息處理完就返回。 函數(shù)SendDlgItemMessage()函數(shù)用于向?qū)υ捒蛑兄付ǖ目丶l(fā)送消息,直到目標控件處理完收到的消息,該函數(shù)才返回。,MFC將這三個函數(shù)封裝為CWnd窗口類的成員函數(shù),封裝了目標窗口句柄,它們將向調(diào)用它的窗口對象發(fā)送或寄送消息,如pMyVi

20、ew-SendMessage()的調(diào)用形式表示向pMyView所指對象發(fā)送消息。 與用戶輸入相關(guān)的消息(如鼠標消息和鍵盤消息)通常是以寄送(Post)的方式發(fā)送,以便這些用戶輸入可以由運行較緩慢的系統(tǒng)進行緩沖處理。而其它消息通常是以傳送(Send)的方式發(fā)送。,手工處理消息映射,創(chuàng)建自己的消息映射的具體過程: 定義自己的消息ID:MFC允許用戶自定義消息,常量WM_USER(為0 x0400)與第一個自定義消息值相對應(yīng),用戶必須為自己的消息定義相對于WM_USER的偏移值。利用#define語句定義自己的消息,例如: #define WM_USER 0X0400 #define WM_USER

21、1 WM_USER+0 #define WM_USER2 WM_USER+1,是對應(yīng)的消息處理函定義消息映射:在BEGIN_MESSAGE_MAP()之后,END_MESSAGE_MAP()之前加入消息映射語句: ON_MESSAGE(message, memberFxn) 其中,message是消息名標識,memberFxn數(shù)。 在cpp文件中定義消息處理函數(shù),對消息進行響應(yīng): 自定義消息處理函數(shù)的聲明:必須在函數(shù)返回類型前面加上afx_msg標識,如: afx_msg LRESULT memberFxn (WPARAM wParam , LPARAM lParam); 其中,參數(shù)wPara

22、m、lParam用于傳遞消息的兩個附加信息。 在需要發(fā)送消息的地方發(fā)送消息:可用CWnd:SendMessage()函數(shù)或CWnd: PostMessage()函數(shù)發(fā)送消息。,例 編寫一個自定義消息應(yīng)用程序,程序啟動后設(shè)置一個定時器,在WM_TIMER的消息處理函數(shù)中發(fā)送一個用戶自定義消息,在對應(yīng)的自定義消息處理函數(shù)中以動畫的形式旋轉(zhuǎn)顯示一行文本。,基本思路: 用WM_TIMER消息處理函數(shù)發(fā)送消息; 啟動定時器 銷毀定時器 用自定義消息完成動畫旋轉(zhuǎn)顯示功能。 自定義消息ID 定義消息映射 定義消息處理函數(shù),具體過程: 1首先利用MFC AppWizardexe向?qū)?chuàng)建一個名為Rotate的應(yīng)

23、用程序。利用ClassWizard類向?qū)镃RotateView類生成消息WM_CREATE的消息處理函數(shù),通過設(shè)置定時器在指定的時間間隔向窗口發(fā)送WM_TIMER消息。 SetTimer(1,200,NULL); / 啟動定時器 2在文件RotateView.cpp開始位置定義一個用戶自定義消息: #define WM_MYMESSAGE WM_USER+1 利用ClassWizard為CRotateView類生成消息WM_TIME的消息處理函數(shù):SendMessage(WM_MYMESSAGE);,3在類CRotateView的定義中聲明自定義消息處理函數(shù): afx_msg LRESULT

24、 OnMyMessage( WPARAM wParam, LPARAM lParam); 在文件RotateView.cpp消息映射BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP之間添加自定義消息映射宏: ON_MESSAGE(WM_MYMESSAGE,OnMyMyessage) 4在類CRotateView的定義中聲明一個private屬性、int型的成員變量m_dEscapement,它表示文本顯示角度,并在類CRotateView的構(gòu)造函數(shù)中初始化:m_dEscapement=0; 5利用ClassWizard生成消息WM_DESTROY的消息處理函數(shù),在銷毀已創(chuàng)建

25、的定時器:KillTimer(1);,6在文件RotateView.cpp中手工添加自定義消息處理函數(shù)實現(xiàn)代碼,完成以動畫形式旋轉(zhuǎn)顯示一行文本的功能。 LRESULT CE6_6View:OnMyMessage(WPARAM wParam,LPARAM lParam) CClientDC dc(this); m_dEacapement=(m_dEacapement+100)%3600; CFont fontRotate; fontRotate.CreateFont(30,0,m_dEacapement,0,0,0,0,0,0,0,0,0,0,0); CFont *pOldFont=dc.Sel

26、ectObject( ,如果不考慮自定義消息,可以采用其他方式: WM_TIMER消息處理函數(shù): 調(diào)用文本顯示函數(shù) 旋轉(zhuǎn)變量的計算 定義一個函數(shù)用來顯示文本 定義一個變量用于文本的位置計算,進入下一節(jié),第三章文檔視圖結(jié)構(gòu):MFC的三種窗體類型,在 MFC 中,文檔是真正的數(shù)據(jù)載體,視圖是文檔的顯示界面,對應(yīng)于同一個文檔,可 能存在多個視圖界面,需要另外一種東西將界面管理起來,即框架。 SDI單文檔窗口:一次只處理一個文檔,譬如記事本,繪圖板; MDI多文檔窗口:可同時處理多個文檔,也意味著需要更多的額外編程工作。并不只是要跟蹤所有打開的文檔,還要提供 Window 菜單來管理特殊的程序特性;

27、Dialog對話框窗口:通常只需要顯示少量的數(shù)據(jù)和獲取少量的用戶輸入,除了節(jié)省資源外,對話框版本的應(yīng)用程序的加載速度也更快些;,文檔和視圖的四個核心類,1.Cdocument(或COleDocument):該類負責(zé)存儲和管理程序的數(shù)據(jù),并為自定義的文檔類提供基礎(chǔ)的功能。一個文檔代表一個數(shù)據(jù)單元,用戶可以通過文件菜單上的“打開”命令打開文檔,或通過文件菜單上的“保存”命令保存文檔。,2.Cview類或其派生類:該類為自定義的視圖類提供了基礎(chǔ)的功能。一個視圖附加到一個文檔并扮演一個文檔和用戶的中間人角色:視圖顯示文檔的外觀到屏幕上,并把用戶的輸入翻譯成對文檔的操作。此外,視圖類還負責(zé)打印和打印預(yù)覽

28、的顯示。 CView 最常用的函數(shù)是 GetDocument,這個函數(shù)用于返回與此視圖關(guān)聯(lián)的文檔。同時CView 具有窗口類的功能,可以方便的定義消息處理函數(shù),MFC 定義了一個非常好的、在“文檔-視圖-框架”之間的消息傳遞機制。,3.CFrameWnd類:該類支持一個文檔的一個或多個視圖的框架,框架窗口類定義了一個視圖的容器。一個 SDI 程序只使用一個框架窗口CFrameWnd 類作為程序的頂層窗口提供視圖的框架。一個 MDI 程序使用兩種不同類型的框架窗口CMDIFrameWnd 作為頂層窗口,CMDIChildWnd 作為浮動窗口,為程序文檔提供框架。,4. CDocTemplate(

29、CSingleDocTemplate 或 CMultiDocTemplate):文檔模板類支持某種類型的文檔并管理這種類型的文檔、視圖和框架窗口對象。,文檔模板,為了管理創(chuàng)建文檔、視圖和框架窗口的復(fù)雜過程,MFC 框架使用兩種文檔模板類:CSingleDocTemplate 類為 SDI(單文檔)程序提供支持CMultiDocTemplate 類為 MDI(多文檔)程序提供支持。一個 CSingleDocTemplate 類可以一次創(chuàng)建和存儲一個類型的文檔。 文檔對象由程序?qū)ο髣?chuàng)建并維護,在程序的 InitInstance 方法中完成的一個關(guān)鍵任務(wù)是創(chuàng)建一個或多個適當(dāng)類型的文檔模板,程序?qū)ο鬄?/p>

30、模板列表中的每個文檔模板存儲一個指針,提供一個接口用來添加文檔模板。如果需要支持兩個或更多的文檔類型,就應(yīng)該為每種文檔類型添加一個 AddDocTemplate 的調(diào)用。,多文檔和多視圖,文檔-視圖程序不僅局限在一個文檔和基于文檔數(shù)據(jù)的視圖,通過使用 MFC 的 Splitter窗口類,一個單文檔接口(SDI)程序可以針對同一個文檔實現(xiàn)兩個或多個視圖劃分框架窗口客戶區(qū)。文檔-視圖結(jié)構(gòu)可以擴展到多文檔接口(MDI)程序,以支持一個文檔的多視圖、多個打開的文檔,甚至多個文檔類型。,MDI 程序和 SDI 程序的主要不同,1.MDI 程序從 CMDIFrameWnd 類繼承頂層框架窗口,而不是 CF

31、rameWnd 類。 2.MDI 程序使用基于 CMDIChildWnd 類的子類來表示子框架窗口。 3.MDI 程序使用 CMultiDocTemplate 而不是 CSingleDocTemplate 來創(chuàng)建文檔模板。 4.在 CMultiDocTemplate 類中引用的框架窗口是子框架窗口類而不是頂層框架窗口。 5.MDI 程序有至少兩個菜單資源,當(dāng)沒有文檔打開時顯示一個菜單,當(dāng)有至少一個文檔打開時顯示另一個菜單。,單文檔框架的初始化,BOOL CSinglePadApp:InitInstance() / 使程序添加對 OLE 控件的包容支持 AfxEnableControlConta

32、iner(); #if def _AFXDLL /當(dāng)使用 MFC 動態(tài)庫時,使程序控件具有 3D 外觀 Enable3dControls(); #else /當(dāng)使用 MFC 靜態(tài)庫時,使程序控件具有 3D 外觀 Enable3dControlsStatic(); #endif / 程序用來存儲配置信息的注冊表值 SetRegistryKey(_T(Local AppWizard-Generated Applications); / 加載標準的 INI 文件選項(包括 MRU) LoadStdProfileSettings(); / 注冊文檔模板 CSingleDocTemplate* pDoc

33、Template;,pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, / 資源 ID,文檔的名稱 RUNTIME_CLASS(CSinglePadDoc), / 文檔 RUNTIME_CLASS(CMainFrame), / 主要的 SDI 框架窗口 RUNTIME_CLASS(CSinglePadView); / 視圖 / 把注冊的文檔模板添加到程序中 AddDocTemplate(pDocTemplate); / 解析命令行完成如標準 Shell 命令、DDE、文件打開操作 CCommandLineInfo cmdInfo; Par

34、seCommandLine(cmdInfo); / 處理命令行中的命令 if (!ProcessShellCommand(cmdInfo) return FALSE; / 顯示和更新窗口 m_pMainWnd-ShowWindow(SW_SHOW); m_pMainWnd-UpdateWindow(); return TRUE; ,多文檔框架的初始化,BOOL CMultiPadApp:InitInstance() AfxEnableControlContainer(); / 使程序添加對 OLE 控件的包容支持 #if def _AFXDLL Enable3dControls(); / 使程

35、序控件具有 3D 外觀,當(dāng)使用 MFC 動態(tài)庫時。 #else Enable3dControlsStatic(); / 使程序控件具有 3D 外觀, #endif / 程序用來存儲配置信息的注冊表值 SetRegistryKey(_T(Local AppWizard-Generated Applications); LoadStdProfileSettings(); / 加載標準的 INI 文件選項(包括 MRU) / 注冊文檔模板 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MULTIP

36、TYPE, / MDI 窗口的資源 RUNTIME_CLASS(CMultiPadDoc), / MDI 文檔 RUNTIME_CLASS(CChildFrame), / MDI 子框架 RUNTIME_CLASS(CMultiPadView); / MDI 視圖,/ 把注冊的文檔模板添加到程序中 AddDocTemplate(pDocTemplate); / 創(chuàng)建 MDI 主窗口 CMainFrame* pMainFrame = new CMainFrame; / 加載主窗口和主資源 if (!pMainFrame-LoadFrame(IDR_MAINFRAME) return FALSE;

37、 m_pMainWnd = pMainFrame; / 解析命令行完成如標準 Shell 命令、DDE、文件打開操作 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); / 處理命令行中的命令 if (!ProcessShellCommand(cmdInfo) return FALSE; / 顯示和更新窗口 m_pMainWnd-ShowWindow(SW_SHOW); m_pMainWnd-UpdateWindow(); return TRUE; ,例子:生成一個多文檔記事本,視圖選擇為CEditView為基類,不用寫一行代碼就實現(xiàn)了一個

38、記事本,可以保存,打開文檔文件,例子:實現(xiàn)多文檔的MDI程序,更改對應(yīng)的類名為上圖所示,為了創(chuàng)建一個新的文檔模板,需要建立三個類,即 CBallFrame(子框架窗口類)、 CBallDoc(文檔類)、CBallView(視圖類)。,添加IDR_MULTBTYPE菜單資源中NewHello,New Ball兩個菜單項,在CMDIApp類中添加新增的兩個菜單項的響應(yīng)函數(shù),在MultiBall.cpp文件中添加三個子類的頭文件,插入一個新的菜單資源IDR_BALLTYPE,BOOL CMDIApp:InitInstance() / 加Hello模板到模板列表 CMultiDocTemplate*

39、pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MULTIBTYPE, RUNTIME_CLASS(CHelloDoc), RUNTIME_CLASS(CHelloFrame), / custom MDI child frame RUNTIME_CLASS(CHelloView); AddDocTemplate(pDocTemplate); / 加球模板到模板列表 CMultiDocTemplate* pBallTemplate = new CMultiDocTemplate( IDR_BALLTYPE, RUNTIME_CLAS

40、S(CBallDoc), RUNTIME_CLASS(CBallFrame), / custom MDI child frame RUNTIME_CLASS(CBallView); AddDocTemplate(pBallTemplate); / create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame-LoadFrame(IDR_MAINFRAME) return FALSE; m_pMainWnd = pMainFrame; / The main window has been

41、 initialized, so show and update it. pMainFrame-ShowWindow(m_nCmdShow); pMainFrame-UpdateWindow(); return TRUE; ,添加新建文檔的響應(yīng)函數(shù):OnNewHello,OnNewBall / 下面兩個菜單命令處理函數(shù)根據(jù)模板列表創(chuàng)建一個相應(yīng)的新的視圖文檔 void CMDIApp:OnNewHello() / 搜索模板列表里包含Hello串的文檔模式 POSITION curTemplatePos = GetFirstDocTemplatePosition(); while(curTempl

42、atePos != NULL) CDocTemplate* curTemplate = GetNextDocTemplate(curTemplatePos); CString str; curTemplate-GetDocString(str, CDocTemplate:docName); if(str = _T(Hello) curTemplate-OpenDocumentFile(NULL); return; AfxMessageBox(No Hello Template);,void CMDIApp:OnNewBall() / 搜索模板列表里包含Ball串的文檔模式 POSITION c

43、urTemplatePos = GetFirstDocTemplatePosition(); while(curTemplatePos != NULL) CDocTemplate* curTemplate = GetNextDocTemplate(curTemplatePos); CString str; curTemplate-GetDocString(str, CDocTemplate:docName); if(str = _T(Ball) curTemplate-OpenDocumentFile(NULL); return; AfxMessageBox(No Ball Template)

44、;,修改字符串資源中IDR_MULTIBTYPE的屬性值,插入新的字符串資源IDR_BALLTYPE,并設(shè)置屬性值,將CHelloView更改繼承自CEditView類:替換CHelloView類源文件與頭文件中所有的CView為CEditView; 更改CHelloDoc類中Serialize序列化函數(shù)的實現(xiàn)為:(CEditView*)m_viewList.GetHead()-SerializeRaw(ar); 這樣就可以實現(xiàn)將CHelloView由普通的視圖類調(diào)整為可以編輯保存的編輯視圖對象; 在CBallView的OnDraw()函數(shù)中添加代碼如下: CRect rect; GetCli

45、entRect(rect); pDC-SetTextAlign(TA_BASELINE | TA_CENTER); / 設(shè)置文本排列居中 pDC-SetTextColor(RGB(255,0,0); / 設(shè)置文本顏色 pDC-SetBkMode(TRANSPARENT); / 設(shè)置背景模式為透明 pDC-TextOut(rect.Width() / 2, rect.Height() / 2, Ball View, 9);,例子二 單文檔多視圖(分割視圖),1.首先創(chuàng)建一個MFC單文檔應(yīng)用程序。 2.添加4個MFC類TopLView、BottomLView、TopRView、BottomRVie

46、w,基類為CView。 3.添加一個MFC類CControlForm,基類為CFormView,對話框ID默認。 4.創(chuàng)建一個切分類,如MySplitter,基類為CSplitterWnd(默認基類選項中無此類,可以先選擇CFrameWnd類,生成后再修改為CSplitterWnd類)。 5.在框架類Cmainframe的頭文件中,添加2個MySplitter的變量(因為下面要進行兩次切分操作m_wndSplitter,m_wndSplitter2)。 6.重寫框架類CMainframe的OnCreateClient函數(shù),如下: /第一次靜態(tài)切分CreateStatic,一行兩列 if (!m

47、_wndSplitter.CreateStatic(this,1,2) return FALSE;,/第二次靜態(tài)切分(將第一次切分后的第二列再分為2*2)及所有的子視圖創(chuàng)建(CreateView函數(shù))。 if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CControlForm), CSize(100, 100), pContext) | !m_wndSplitter2.CreateStatic( /注釋掉原有的響應(yīng)函數(shù) 注意:記得在Mainfrm.h中添加以上五個視圖類的頭文件: #include ControlForm.h#include

48、TopLView.h#include TopRView.h#include BottomLView.h#include BottomRView.h #include “MySplitter.h” 將CMySplitter的構(gòu)造函數(shù)與析構(gòu)函數(shù)改為public屬性,第四章:簡單繪圖繪制線條,要求:單擊鼠標左鍵并按住拖動后,釋放鼠標左鍵,完成線條的繪圖。 1.新建單文檔類型程序,名為Draw,添加鼠標左鍵按下及釋放的消息響應(yīng)函數(shù); 2.為CDrawView類添加Cpoint類型成員變量m_ptOrigin;,使用SDK全局函數(shù)繪制線條:,GetDc可以在任意位置繪圖,前提是得到任意繪圖區(qū)域的句柄,必

49、須記住釋放資源,利用MFC的CDC類繪圖,默認獲得的是當(dāng)前上下文環(huán)境下的設(shè)備句柄,此處獲得的是CDrawView對象的指針句柄,利用MFC的CClientDC類繪圖,CClientDC類的構(gòu)造函數(shù)會調(diào)用GetDC,析構(gòu)函數(shù)會調(diào)用ReleaseDC,因此不需要顯式的釋放資源;,當(dāng)將this更改為GetParent()函數(shù)時,則可以在窗口的整個區(qū)域繪圖包括菜單欄、工具欄,非客戶區(qū)域;因為CDrawView是由CMainFrame對象生成的,因此此處獲得的即為整個程序的框架窗口設(shè)備句柄;,利用MFC的CWindowDC類繪圖,獲得了桌面窗口的句柄,故可以實現(xiàn)在整個桌面繪圖;,第五章:菜單操作,Get

50、Menu獲得菜單項,GetSubMenu獲得菜單項的子菜單,checkMenuItem設(shè)置/刪除菜單項的復(fù)選標志,設(shè)置默認菜單項,將會以粗體方式顯示,加載圖標菜單項,獲得默認的菜單項所能加載的位圖的尺寸,并已消息框方式顯示出來,此處為13*13,在位圖資源編輯器中編輯位圖,使之大小為13*13,也可以采用其他工具調(diào)整位圖大?。?移除和加載菜單項,Cmenu為局部對象,可能導(dǎo)致異常,要么將menu對象更改為CMainFrame的成員變量,要么增加一條語句:menu.Detach();,創(chuàng)建快捷菜單(右鍵菜單) 1.在資源選項的Menu文件夾下右鍵單擊,選擇Insert Menu 命名為 IDR_

51、POPUP_MENU 在里面填一些菜單項; 2.選中視圖類,在屬性中選擇消息:WM_CONTEXTMENU,添加函數(shù)函數(shù); void CMyDrawView:OnContextMenu(CWnd* pWnd, CPoint point) / TODO: 在此處添加消息處理程序代碼 CMenu m_menu; m_menu.LoadMenuW(IDR_POPUP_MENU); CMenu *popupmenu = m_menu.GetSubMenu(0); popupmenu-TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, poi

52、nt.y, pWnd, 0); ,第六章 對話框,對話框的作用: 主要功能是用于接收用戶的輸入數(shù)據(jù); 還可用來顯示提示信息(如程序啟動時顯示版權(quán)和運行進度信息)。 在MFC中,對話框的功能被封裝在CDialog類中,而CDialog類是CWnd類的派生類。作為窗口,對話框和其它窗口一樣具有窗口的一切功能。 對話框的典型應(yīng)用: 通過菜單命令或工具欄按鈕打開一個對話框; 對話框也可以作為一個程序的主界面。,對話框: 是Windows應(yīng)用程序中一種常用的資源,其主要功能是輸出信息和接收用戶的輸入數(shù)據(jù)。 控件: 是嵌入在對話框中或其它父窗口中的一個特殊的小窗口,它用于完成不同的輸入、輸出功能。,基于對

53、話框的應(yīng)用程序,可以直接利用MFC AppWizard向?qū)?chuàng)建一個基于對話框的應(yīng)用程序,這種程序運行后首先出現(xiàn)一個對話框。在向?qū)У牡谝徊竭x擇Dialog Based項。因為對話框應(yīng)用程序一般不包含文檔,故不支持數(shù)據(jù)庫和復(fù)合文檔。 按照對話框應(yīng)用程序向?qū)崾镜牟襟E進行操作就得到一個對話框應(yīng)用程序項目,出現(xiàn)對話框編輯器和控件工具欄浮動窗口,它們采用的是一種所見即所得的可視化工作方式。利用向?qū)?chuàng)建應(yīng)用程序的框架后,程序員可根據(jù)程序具體功能要求添加代碼。 當(dāng)一個有模式對話框打開時,用戶只能與該對話框進行交互,而其他用戶界面對象收不到輸入信息。平時所遇到的大部分對話框都是有模式對話框。無模式對話框則不然

54、,該對話框并不阻止用戶的輸入。,對話框的初始化,OnInitDialog():該函數(shù)是由消息 WM_INITDIALOG 來激活的,但此消息比較特別,它不用添加到消息映射表中。該函數(shù)用來進行對話框的初始化,為使用對話框進行準備工作。該函數(shù)的原型為:virtual void OnInitDialog();而且CDialog 類中提供了它的默認實現(xiàn),即在 CDialog 的派生類中將根據(jù)需要決定是否重寫該函數(shù)。,對話框的結(jié)束,在 CDialog 類中存在兩個關(guān)鍵函數(shù) OnOK()和 OnCancel(),這兩個函數(shù)用于響應(yīng)單擊OK 按鈕(控件 ID 為 IDOK)和 Cancel 按鈕(控件 ID

55、 為 IDCANCEL)的消息,這些消息也不用添加到消息映射表里。兩個函數(shù)都用于關(guān)閉對話框并返回對話框擁有者的窗口,但返回結(jié)果不同。OnOK()函數(shù)返回 IDOK,并把對話框輸入的數(shù)據(jù)結(jié)果提供給對話框的擁有者,而 OnCancel()函數(shù)返回 IDCANCEL,但并不把對話框輸入的數(shù)據(jù)結(jié)果提供給對話框的擁有者。,有關(guān)對話框的常用處理函數(shù) CDialog:CDialog() 通過調(diào)用派生類構(gòu)造函數(shù),根據(jù)對話框資源模板定義一個對話框。 CDialog:DoModal() 激活模態(tài)對話框,顯示對話框窗口。 CDialog:Create() 根據(jù)對話框資源模板創(chuàng)建非模態(tài)對話框窗口。如果對話框不是Vis

56、ible屬性,還需通過調(diào)用CWnd:ShowWindow()函數(shù)顯示非模態(tài)對話框窗口。,CDialog:OnOk() 單擊OK按鈕時調(diào)用該函數(shù),接收對話框輸入數(shù)據(jù),關(guān)閉對話框。 CDialog:OnCancel() 單擊Cancel按鈕或按Esc鍵時調(diào)用該函數(shù),不接收對話框輸入數(shù)據(jù),關(guān)閉對話框。 CDialog:OnInitDialog() WM_INITDIALOG消息處理函數(shù),在調(diào)用DoModal或Create函數(shù)時系統(tǒng)發(fā)送WM_INITDIALOG消息,在顯示對話框前調(diào)用該函數(shù)進行初始化。 CDialog:EndDialog() 用于關(guān)閉模態(tài)對話框窗口。,CWnd:ShowWindow(

57、) 顯示或隱藏對話框窗口 CWnd:DestroyWindow() 關(guān)閉并銷毀非模態(tài)對話框 CWnd:UpdateData() 通過調(diào)用DoDataExchange()設(shè)置或獲取對話框控件的數(shù)據(jù) CWnd:DoDataExchange() 被UpdateData()調(diào)用以實現(xiàn)對話框數(shù)據(jù)交換,不能直接調(diào)用。,CWnd:GetWindowText() 獲取對話框窗口的標題 CWnd:SetWindowText() 修改對話框窗口的標題 CWnd:GetDlgItemText() 獲取對話框中控件的文本內(nèi)容 CWnd:SetDlgItemText() 設(shè)置對話框中控件的文本內(nèi)容 CWnd:GetDl

58、gItem() 獲取控件或子窗口的指針 CWnd:MoveWindow() 用于移動對話框窗口 CWnd:EnableWindow() 使窗口處于禁用或可用狀態(tài),對話框數(shù)據(jù)交換DDX和驗證DDV,在對話框中實現(xiàn)用戶數(shù)據(jù)輸入和輸出的一般方法是通過ClassWizard類向?qū)υ捒蚩丶c成員變量相關(guān)聯(lián),利用對話框數(shù)據(jù)交換DDX(Dialog Data Exchange)和驗證DDV(Dialog Data Validation)機制實現(xiàn)數(shù)據(jù)的輸入和輸出。 DDX是將成員變量與對話框控件相連接,完成數(shù)據(jù)在成員變量與控件之間的交換。 DDV用于數(shù)據(jù)的校驗,它能自動校驗輸入的數(shù)據(jù)是否符合設(shè)計要求。 對話框數(shù)據(jù)交換與驗證都是通過DoDataExchange()完成。,當(dāng)利用ClassWizard類向?qū)砑映蓡T變量時,用戶如果在窗口的左下角輸入數(shù)據(jù)的范圍,ClassWizard將自動加入函數(shù)DDV的調(diào)用代碼。 例如,當(dāng)添加一個UINT型的成員變量m_nInput時指定它的最小值和最大值分別為0和100,則C

溫馨提示

  • 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

提交評論