版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1、第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.1 概述概述11.2 文檔類文檔類11.3 視圖類視圖類11.4 應用實例應用實例第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.1 概述概述第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.1.1 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu) 在文檔在文檔/視圖結(jié)構(gòu)中,文檔是一種數(shù)據(jù)源。視圖結(jié)構(gòu)中,文檔是一種數(shù)據(jù)源。 視圖類在文檔和用戶之間起中介作用。視圖類在文檔和用戶之間起中介作用。 視圖可以直接或間接地訪問文檔類中的成員變量視圖可以直接或間接地訪問文檔類中的成員變量,它從,它從文檔類中文檔類中(而不是從存儲介質(zhì)中而不是從存儲介
2、質(zhì)中)將文檔的部分或全部的數(shù)將文檔的部分或全部的數(shù)據(jù)取出來,然后在屏幕上顯示。據(jù)取出來,然后在屏幕上顯示。 第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)文檔和視圖的關系文檔和視圖的關系 文檔文檔/視圖結(jié)構(gòu)的最大特點:把數(shù)據(jù)操作和數(shù)據(jù)表示分離開視圖結(jié)構(gòu)的最大特點:把數(shù)據(jù)操作和數(shù)據(jù)表示分離開來,與數(shù)據(jù)庫管理系統(tǒng)提供的數(shù)據(jù)庫與視圖的關系一致。來,與數(shù)據(jù)庫管理系統(tǒng)提供的數(shù)據(jù)庫與視圖的關系一致。 所有對數(shù)據(jù)的修改由文檔對象來完成,用視圖調(diào)用這個文所有對數(shù)據(jù)的修改由文檔對象來完成,用視圖調(diào)用這個文檔對象的方法來訪問和更新數(shù)據(jù)。檔對象的方法來訪問和更新數(shù)據(jù)。數(shù)據(jù)數(shù)據(jù)文檔文檔視圖視圖020040060012345
3、ABCDA12345ABCD15565587982232337310934542265143467447818752421190203第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.1.2 文檔和視圖的相互作用文檔和視圖的相互作用 在在MFC應用程序框架中,文檔應用程序框架中,文檔/視圖結(jié)構(gòu)的關系主要體現(xiàn)視圖結(jié)構(gòu)的關系主要體現(xiàn)在文檔類和視圖類對象的相互作用和相互訪問。在文檔類和視圖類對象的相互作用和相互訪問。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu) CView:GetDocument( )返回文檔類的指針,通過該指針在視圖類中訪問并更新文檔數(shù)據(jù)。返回文檔類的指針,通過該指針在視圖類中訪問并更新文
4、檔數(shù)據(jù)。 CDocument:UpdateAllViews (CView *pSender,LPARAM lHint=0,Cobject *pHint=NULL)該函數(shù)通知與文檔相連的所有或部分視圖,更新窗口內(nèi)容。在該函數(shù)通知與文檔相連的所有或部分視圖,更新窗口內(nèi)容。在MFC應用程序框應用程序框架中,由于文檔和視圖的架中,由于文檔和視圖的一對多一對多關系,當用戶在一個視圖中修改文檔后,本關系,當用戶在一個視圖中修改文檔后,本視圖將發(fā)生改變,相應地與文檔相連的其他視圖也應與更新后的文檔內(nèi)容保視圖將發(fā)生改變,相應地與文檔相連的其他視圖也應與更新后的文檔內(nèi)容保持一致。這時,本視圖便可以調(diào)用該函數(shù)向其
5、他視圖窗口發(fā)出持一致。這時,本視圖便可以調(diào)用該函數(shù)向其他視圖窗口發(fā)出WM_PAINT消息,通知它們更新。消息,通知它們更新。 CView:OnUpdate( )該函數(shù)是一個虛函數(shù),當應用程序調(diào)用該函數(shù)是一個虛函數(shù),當應用程序調(diào)用CDocument:UpdateAllViews()函數(shù)時,函數(shù)時,應用程序框架會相應地調(diào)用它。還可在應用程序視圖類的派生類中,直接調(diào)應用程序框架會相應地調(diào)用它。還可在應用程序視圖類的派生類中,直接調(diào)用用OnUpdate()函數(shù),函數(shù),OnUpdate()函數(shù)訪問文檔得到文檔的數(shù)據(jù),然后更新函數(shù)訪問文檔得到文檔的數(shù)據(jù),然后更新視圖的數(shù)據(jù)成員或控制來反應這些變化。另外,視
6、圖的數(shù)據(jù)成員或控制來反應這些變化。另外,OnUpdate()函數(shù)可以使視圖函數(shù)可以使視圖的一部分無效,導致視圖的的一部分無效,導致視圖的OnDraw()使用文檔數(shù)據(jù)來在窗口中重畫。使用文檔數(shù)據(jù)來在窗口中重畫。 CView:OnInitialUpdate( )該函數(shù)也是一個虛函數(shù),當應用程序啟動時,或者用戶執(zhí)行菜單命令該函數(shù)也是一個虛函數(shù),當應用程序啟動時,或者用戶執(zhí)行菜單命令File-New或或File-Open時,就會調(diào)用這個虛函數(shù)。如果要初始化視圖對象,可時,就會調(diào)用這個虛函數(shù)。如果要初始化視圖對象,可在視圖類的派生類中重載該函數(shù),添加初始化代碼。當應用程序啟動時,先在視圖類的派生類中重載
7、該函數(shù),添加初始化代碼。當應用程序啟動時,先調(diào)用調(diào)用OnCreate()函數(shù),接著就調(diào)用函數(shù),接著就調(diào)用OnInitialUpdate()函數(shù)。函數(shù)。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)MFC類中獲得其它類指針類中獲得其它類指針 1. 從視圖類獲得文檔類的指針從視圖類獲得文檔類的指針 CTestDoc *pDoc=(CTestDoc*)GetDocument(); 視圖通過視圖通過GetDocument()函數(shù)獲得指向文檔對象的指針,并通過函數(shù)獲得指向文檔對象的指針,并通過該指針訪問文檔類的成員函數(shù)或數(shù)據(jù)成員獲取數(shù)據(jù)。該指針訪問文檔類的成員函數(shù)或數(shù)據(jù)成員獲取數(shù)據(jù)。視圖把數(shù)據(jù)顯示于計算機屏幕
8、上,用戶通過與視圖的交互來查視圖把數(shù)據(jù)顯示于計算機屏幕上,用戶通過與視圖的交互來查看數(shù)據(jù)并對數(shù)據(jù)進行修改,然后看數(shù)據(jù)并對數(shù)據(jù)進行修改,然后視圖通過相關聯(lián)的文檔類的成視圖通過相關聯(lián)的文檔類的成員函數(shù)將經(jīng)過修改的數(shù)據(jù)傳遞給文檔對象員函數(shù)將經(jīng)過修改的數(shù)據(jù)傳遞給文檔對象。文檔對象獲得修改過的數(shù)據(jù)之后,對其進行必要的修改,最后文檔對象獲得修改過的數(shù)據(jù)之后,對其進行必要的修改,最后保存到永久介質(zhì)(如磁盤文件)中。保存到永久介質(zhì)(如磁盤文件)中。2. 從文檔類取得視圖類的指針從文檔類取得視圖類的指針 CDocument類提供了兩個函數(shù)用于視圖類的定位類提供了兩個函數(shù)用于視圖類的定位: GetFirstVie
9、wPosition() 和和 GetNextView() 第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)MFC類中獲得其它類指針類中獲得其它類指針(2)3. 從主幀窗口類獲得視圖類指針從主幀窗口類獲得視圖類指針: CFrameWnd:GetActiveView() 4.從視圖類中獲得主窗口類指針從視圖類中獲得主窗口類指針: CWnd:GetParentFrame()或或AfxGetMainWnd();5.在任何類中獲得應用程序類在任何類中獲得應用程序類:用用MFC全局函數(shù)全局函數(shù)AfxGetApp() 6.從應用程序類中獲得主窗口類從應用程序類中獲得主窗口類 m_pMainWnd成員成員(CWinT
10、hread類的公有數(shù)據(jù)成員,派生關系:類的公有數(shù)據(jù)成員,派生關系:CWinThread -CWinApp -應用程序類應用程序類)注意:注意: A.在類在類A中獲得類中獲得類B的指針時,類的指針時,類A應包含類應包含類B的頭文件。的頭文件。B.在很多時候要進行強制類型轉(zhuǎn)換,并要注意括號的括法。在很多時候要進行強制類型轉(zhuǎn)換,并要注意括號的括法。 由于派生類和父類指針類型的兼容,使明確區(qū)分各個類變得十分重要。由于派生類和父類指針類型的兼容,使明確區(qū)分各個類變得十分重要。在拿不準的時候,最好加上強制類型轉(zhuǎn)換。在拿不準的時候,最好加上強制類型轉(zhuǎn)換。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.1.3
11、SDI和和MDIVC的的MFC庫支持三庫支持三種不同的種不同的應用程序應用程序單文檔界面單文檔界面(SDI)多文檔界面多文檔界面(MDI)基于對話框的應用程序基于對話框的應用程序SDI的應用程序的應用程序只有一個窗口只有一個窗口MDI的應用程序每次的應用程序每次可以讀寫多個文件或可以讀寫多個文件或文檔,可同時對多個文檔,可同時對多個文檔進行操作,可以文檔進行操作,可以有多個子窗口有多個子窗口主主要要差差別別SDI由框架窗口類由框架窗口類CFrameWnd 派生派生CMainFrame類類MDI有有CMDIFrameWnd和和CMDIChildWnd兩個框架窗口類,前一個派生兩個框架窗口類,前一
12、個派生CMainFrame類,負責菜單等界面元素的主框架窗口管理類,負責菜單等界面元素的主框架窗口管理;后一個派生;后一個派生CChildFrame類,負責相應的類,負責相應的文檔及其視圖的子框架維護。文檔及其視圖的子框架維護。使用使用AppWizard創(chuàng)創(chuàng)建建SDI和和MDI界面界面的應用程序的過程的應用程序的過程幾乎完全一樣幾乎完全一樣第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)SDI和和MDI 相同點:相同點:MDI應用程序和應用程序和SDI程序都提供一個程序都提供一個File菜單,菜單,用于新建、打開、保存文檔。用于新建、打開、保存文檔。 不同點:不同點:(1) MDI一般還提供一個一般還
13、提供一個Close菜單項,用于關閉當前打開的菜單項,用于關閉當前打開的文檔。文檔。(2) MDI應用程序有一個窗口菜單,用于管理所有打開的子應用程序有一個窗口菜單,用于管理所有打開的子窗口,包括窗口的新建、關閉、層疊、平鋪等。關閉一窗口,包括窗口的新建、關閉、層疊、平鋪等。關閉一個窗口時,窗口內(nèi)的文檔將被自動關閉。個窗口時,窗口內(nèi)的文檔將被自動關閉。文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu) 在在文檔文檔/視圖視圖結(jié)構(gòu)中結(jié)構(gòu)中對數(shù)據(jù)進行管理和維對數(shù)據(jù)進行管理和維護,數(shù)據(jù)保存在護,數(shù)據(jù)保存在文檔文檔類類的成員變量中的成員變量中文檔類文檔類通過串行化的過程將數(shù)據(jù)保存到通過串行化的過程將數(shù)據(jù)保存到磁磁盤文件盤文件或
14、或數(shù)據(jù)庫數(shù)據(jù)庫中中文檔類文檔類還可處理來自如菜單、工具欄按鈕還可處理來自如菜單、工具欄按鈕和加速鍵的和加速鍵的WM_COMMAND消息消息除除WM_COMMAND外,文檔外,文檔不能不能處理其處理其它的它的Windows消息消息通過調(diào)用文檔和視圖的接口將通過調(diào)用文檔和視圖的接口將修改的信息反饋給文檔類,實修改的信息反饋給文檔類,實際的數(shù)據(jù)更新仍然由文檔完成際的數(shù)據(jù)更新仍然由文檔完成在文檔和用戶之在文檔和用戶之間起中介作用間起中介作用視圖可以直接或間接的訪問文檔類中的視圖可以直接或間接的訪問文檔類中的成員變量,它從文檔類中成員變量,它從文檔類中(而不是從存而不是從存儲介質(zhì)中儲介質(zhì)中)將文檔中的數(shù)
15、據(jù)取出來,然將文檔中的數(shù)據(jù)取出來,然后在屏幕上顯示文檔的數(shù)據(jù)后在屏幕上顯示文檔的數(shù)據(jù)接收用戶的輸入,并接收用戶的輸入,并接受用戶的接受用戶的修改修改SDI文檔文檔/視圖應用程序示意圖視圖應用程序示意圖 由由CWinApp類派生,管理應用類派生,管理應用程序的初始化,負責保持文檔、程序的初始化,負責保持文檔、視圖、框架窗口類之間的關系,視圖、框架窗口類之間的關系,接收消息,將消息調(diào)度到需要接收消息,將消息調(diào)度到需要的目標窗口中。的目標窗口中。提供一個應用程序的主窗口,提供一個應用程序的主窗口,通常包含一個通常包含一個最大化、最小化最大化、最小化按鈕、標題欄和系統(tǒng)菜單按鈕、標題欄和系統(tǒng)菜單。還。還
16、可處理可處理工具條工具條和和狀態(tài)條狀態(tài)條的創(chuàng)建、的創(chuàng)建、初始化和銷毀。初始化和銷毀。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)視圖視圖通過通過GetDocument成員函數(shù)獲得指向相關成員函數(shù)獲得指向相關聯(lián)的文檔對象的指針聯(lián)的文檔對象的指針通過該指針調(diào)用通過該指針調(diào)用文檔類文檔類的成員函的成員函數(shù)并從文檔中讀數(shù)并從文檔中讀取數(shù)據(jù)取數(shù)據(jù)視圖視圖把數(shù)據(jù)顯把數(shù)據(jù)顯示于計算機屏示于計算機屏幕上幕上用戶通過與用戶通過與視圖視圖的的交互來查看數(shù)據(jù)并交互來查看數(shù)據(jù)并對數(shù)據(jù)進行修改對數(shù)據(jù)進行修改視圖視圖通過相關聯(lián)的通過相關聯(lián)的文文檔類檔類的成員函數(shù)將修的成員函數(shù)將修改的數(shù)據(jù)傳遞給文檔改的數(shù)據(jù)傳遞給文檔對象對象文
17、檔文檔對象獲得修改過的數(shù)據(jù)之后,對象獲得修改過的數(shù)據(jù)之后,對其進行必要的修改,最后可以對其進行必要的修改,最后可以保存到永久介質(zhì)保存到永久介質(zhì)(如磁盤文件如磁盤文件)中中文檔文檔/視圖結(jié)構(gòu)的工作機制視圖結(jié)構(gòu)的工作機制第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)文檔模板類的功能文檔模板類的功能 在在MFC中,中,文檔類文檔類、與文檔類相關聯(lián)的、與文檔類相關聯(lián)的視圖類視圖類以及為視以及為視圖類提供顯示的圖類提供顯示的框架窗口框架窗口都是由文檔模板類創(chuàng)建的。都是由文檔模板類創(chuàng)建的。 每一種文檔類型都有一種文檔模板與之相對應,文檔模每一種文檔類型都有一種文檔模板與之相對應,文檔模板負責創(chuàng)建和管理該文檔類型
18、的所有文檔。板負責創(chuàng)建和管理該文檔類型的所有文檔。 由由AppWizard創(chuàng)建的創(chuàng)建的SDI應用程序的應用程序的5個基類之間的關系個基類之間的關系:創(chuàng)建創(chuàng)建創(chuàng)建創(chuàng)建創(chuàng)建創(chuàng)建創(chuàng)建創(chuàng)建應用程序?qū)ο髴贸绦驅(qū)ο驝WinApp文檔模板文檔模板CSingleDocTemplate文檔對象文檔對象CDocument框架窗口框架窗口CFrameWnd視圖對象視圖對象CView第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.1.4 文檔文檔/視圖結(jié)構(gòu)的特點視圖結(jié)構(gòu)的特點1使程序進一步模塊化使程序進一步模塊化2有利于代碼重用有利于代碼重用不推薦采用文檔不推薦采用文檔/視圖結(jié)構(gòu)的情況主要有以下兩種:視圖結(jié)構(gòu)的情況主
19、要有以下兩種: (1) 不是面向數(shù)據(jù)或數(shù)據(jù)量很小的應用程序,最好不采用文不是面向數(shù)據(jù)或數(shù)據(jù)量很小的應用程序,最好不采用文檔檔/視圖結(jié)構(gòu)。例如一些重要功能的視圖結(jié)構(gòu)。例如一些重要功能的工具程序工具程序,包括磁盤,包括磁盤掃描程序、時鐘程序和一些過程控制程序等。掃描程序、時鐘程序和一些過程控制程序等。 (2) 不需重用不需重用 MFC提供的標準用戶界面功能的程序,如一提供的標準用戶界面功能的程序,如一些些游戲程序游戲程序等,最好不采用文檔等,最好不采用文檔/視圖結(jié)構(gòu)。視圖結(jié)構(gòu)。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.2 文檔類文檔類第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.2.1 文檔類
20、的結(jié)構(gòu)及其方法文檔類的結(jié)構(gòu)及其方法1文檔類的結(jié)構(gòu)文檔類的結(jié)構(gòu)/ class CDocument is the main document data abstraction#ifdef _AFXDLLclass CDocument : public CCmdTarget#elseclass AFX_NOVTABLE CDocument : public CCmdTarget#endifDECLARE_DYNAMIC(CDocument)public:/ ConstructorsCDocument();/ Attributespublic:const CString& GetTitle()
21、 const;virtual void SetTitle(LPCTSTR lpszTitle);第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)const CString& GetPathName() const;virtual void SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU = TRUE);CDocTemplate* GetDocTemplate() const;virtual BOOL IsModified();virtual void SetModifiedFlag(BOOL bModified = TRUE);/ Operat
22、ionsvoid AddView(CView* pView);void RemoveView(CView* pView);virtual POSITION GetFirstViewPosition() const;virtual CView* GetNextView(POSITION& rPosition) const;/ Update Views (simple update - DAG only)void UpdateAllViews(CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL);/ Overridables/
23、Special notificationsvirtual void OnChangedViewList(); / after Add or Remove viewvirtual void DeleteContents(); / delete doc items etc第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)/ File helpersvirtual BOOL OnNewDocument();virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);vir
24、tual void OnCloseDocument();virtual void ReportSaveLoadException(LPCTSTR lpszPathName, CException* e, BOOL bSaving, UINT nIDPDefault);virtual CFile* GetFile(LPCTSTR lpszFileName, UINT nOpenFlags,CFileException* pError);virtual void ReleaseFile(CFile* pFile, BOOL bAbort);/ advanced overridables, clos
25、ing down frame/doc, etc.virtual BOOL CanCloseFrame(CFrameWnd* pFrame);virtual BOOL SaveModified(); / return TRUE if ok to continuevirtual void PreCloseFrame(CFrameWnd* pFrame);/ Implementationprotected:/ default implementationCString m_strTitle;第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)CString m_strPathName;CDocTemplate*
26、 m_pDocTemplate;CPtrList m_viewList; / list of viewsBOOL m_bModified; / changed since last savedpublic:BOOL m_bAutoDelete; / TRUE=delete document when no more viewsBOOL m_bEmbedded; / TRUE = document is being created by OLE#ifdef _DEBUGvirtual void Dump(CDumpContext&) const;virtual void AssertVa
27、lid() const;#endif /_DEBUGvirtual CDocument();/ implementation helpersvirtual BOOL DoSave(LPCTSTR lpszPathName, BOOL bReplace = TRUE);virtual BOOL DoFileSave();virtual void UpdateFrameCounts();void DisconnectViews();void SendInitialUpdate();第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)/ overridables for implementationvirtua
28、l HMENU GetDefaultMenu(); / get menu depending on statevirtual HACCEL GetDefaultAccelerator();virtual void OnIdle();virtual void OnFinalRelease();virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo);friend class CDocTemplate;protected:/ file menu commands/AFX_MSG
29、(CDocument)afx_msg void OnFileClose();afx_msg void OnFileSave();afx_msg void OnFileSaveAs();/AFX_MSG/ mail enablingafx_msg void OnFileSendMail();afx_msg void OnUpdateFileSendMail(CCmdUI* pCmdUI);DECLARE_MESSAGE_MAP();第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)2文檔類的方法文檔類的方法CDocument類提供了文檔類所需要的最基本的功能實類提供了文檔類所需要的最基本的功能實現(xiàn)。提供的
30、方法主要有一般方法和虛擬方法?,F(xiàn)。提供的方法主要有一般方法和虛擬方法。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu) CDocument類提供的虛擬方法,使應用程序可以重寫虛類提供的虛擬方法,使應用程序可以重寫虛擬函數(shù)來提供擬函數(shù)來提供CDocument派生類中的方法。派生類中的方法。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)CDocument類常用方法類常用方法 最常用的是最常用的是SetModifiedFlag()和和UpdateAllViews()。 文檔內(nèi)容被修改后,一般要調(diào)用文檔內(nèi)容被修改后,一般要調(diào)用SetModifiedFlag()來來設定一個標志。設定一個標志。 UpdateAllVi
31、ew()刷新所有和文檔關聯(lián)的視圖。實際上刷新所有和文檔關聯(lián)的視圖。實際上該函數(shù)調(diào)用各個視圖類的該函數(shù)調(diào)用各個視圖類的OnUpdate()函數(shù)。這樣做可函數(shù)。這樣做可以保證各個視圖之間的同步。以保證各個視圖之間的同步。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)文檔數(shù)據(jù)的存儲文檔數(shù)據(jù)的存儲 使用使用AppWizard生成的每一個生成的每一個SDI或或MDI應用程序框架中應用程序框架中都有一個都有一個File菜單,其中包含菜單,其中包含New、Open、Save和和Save As命令。命令。 文檔數(shù)據(jù)需要進行存儲操作。文檔數(shù)據(jù)需要進行存儲操作。 無論是保存文檔還是打開文檔,應用程序都是通過調(diào)用無論是保
32、存文檔還是打開文檔,應用程序都是通過調(diào)用文檔類的文檔類的Serialize成員函數(shù)來完成持續(xù)化(串行化)操作。成員函數(shù)來完成持續(xù)化(串行化)操作。 持續(xù)性持續(xù)性(串行化)在面向?qū)ο蟪绦蛟O計領域中的基本概(串行化)在面向?qū)ο蟪绦蛟O計領域中的基本概念,是指對象可以被持續(xù),即當程序退出時它們可以被念,是指對象可以被持續(xù),即當程序退出時它們可以被保存在磁盤中,而當程序重新運行時又可以從磁盤中讀保存在磁盤中,而當程序重新運行時又可以從磁盤中讀取恢復。對象的這種保存和恢復的過程就稱為取恢復。對象的這種保存和恢復的過程就稱為“串行串行化化”。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)持續(xù)性持續(xù)性 在在MFC
33、中,對象串行化的成員函數(shù)稱為中,對象串行化的成員函數(shù)稱為Serialize()成員函成員函數(shù)。這個函數(shù)提供了將類的數(shù)據(jù)進行存盤和讀取的功能。數(shù)。這個函數(shù)提供了將類的數(shù)據(jù)進行存盤和讀取的功能。 持續(xù)性是持續(xù)性是CObject類具有的性質(zhì)類具有的性質(zhì),其中定義了虛擬的,其中定義了虛擬的Serialize成員函數(shù)。根據(jù)虛擬函數(shù)的繼承性,成員函數(shù)。根據(jù)虛擬函數(shù)的繼承性, CDocument類也具有類也具有持續(xù)性。持續(xù)性。 在大多數(shù)情況下,要通過在大多數(shù)情況下,要通過重載重載Serialize成員函數(shù)來實現(xiàn)文成員函數(shù)來實現(xiàn)文檔的串行化檔的串行化。 Serialize函數(shù)帶有一個函數(shù)帶有一個CArchiv
34、e類型的參數(shù),類型的參數(shù),這是一個與所有打開的文件相關聯(lián)的對象。一般情況下,這是一個與所有打開的文件相關聯(lián)的對象。一般情況下,總是使用總是使用CArchive對象來保存和打開文檔。對象來保存和打開文檔。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.2.2 文檔類的持續(xù)性文檔類的持續(xù)性1文檔類的持續(xù)性原理文檔類的持續(xù)性原理打開一個打開一個AppWizard生成的項目名稱為生成的項目名稱為My的單文檔的單文檔程序,可以看到文檔類程序,可以看到文檔類CMyDoc的聲明如下:的聲明如下:class CMyDoc : public CDocumentprotected: / create from se
35、rialization onlyCMyDoc();DECLARE_DYNCREATE(CMyDoc)/ Attributespublic:/ Operationspublic:/ Overrides/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CMyDoc)第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)public:virtual BOOL OnNewDocument();virtual void Serialize(CArchive& ar);/AFX_VIRTUAL/ Implementationpublic
36、:virtual CMyDoc();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected:/ Generated message map functionsprotected:/AFX_MSG(CMyDoc)/ DO NOT EDIT what you see in these blocks of generated code !/AFX_MSGDECLARE_MESSAGE_MAP();第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)2Se
37、rialize函數(shù)函數(shù) virtual void Serialize(CArchive& ar); CArchive對象是對象是單向單向的,即同一個的,即同一個CArchive對象只能用對象只能用于保存或讀取兩者之一,不能通過同一個于保存或讀取兩者之一,不能通過同一個CArchive對象對象既進行文檔的保存又進行文檔的讀取。既進行文檔的保存又進行文檔的讀取。 在框架創(chuàng)建在框架創(chuàng)建CArchive對象時,只能根據(jù)用戶選擇的是對象時,只能根據(jù)用戶選擇的是“保存保存”(“另存為另存為”)還是)還是“打開打開”設置了設置了CArchive對象的類型??梢允褂脤ο蟮念愋汀?梢允褂肅Archive
38、類的成員函數(shù)類的成員函數(shù)IsStoring來檢索當前來檢索當前CArchive對象的類型,從而得知用戶所期望對象的類型,從而得知用戶所期望的操作是保存還是讀取,從而執(zhí)行不同的操作。的操作是保存還是讀取,從而執(zhí)行不同的操作。 串行化:將對象寫入字節(jié)流和從字節(jié)流恢復對象的操作。串行化:將對象寫入字節(jié)流和從字節(jié)流恢復對象的操作。 串行化除了可以使用文件保存對象之外,還可以通過網(wǎng)串行化除了可以使用文件保存對象之外,還可以通過網(wǎng)絡、串口傳輸對象,因此使用字節(jié)流。絡、串口傳輸對象,因此使用字節(jié)流。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)void CMyDoc:Serialize(CArchive&
39、 ar)if (ar.IsStoring()/如果數(shù)據(jù)要寫入(如果數(shù)據(jù)要寫入(Save或或Save As),),IsStoring()返回返回布爾值布爾值TRUE;如果數(shù)據(jù)是被讀取,則返回;如果數(shù)據(jù)是被讀取,則返回FALSE/ TODO: add storing code herearm_Namem_Age;/重載的插入重載的插入m_Namem_Age;/重載的重載的提取提取操作符執(zhí)行操作符執(zhí)行讀讀操作操作輸入輸入/輸出流處理的是輸出流處理的是ASCII字符,而字符,而archive對象處理的是二進制對象對象處理的是二進制對象將數(shù)據(jù)序列化到存檔時,存檔積累數(shù)據(jù),直到其緩沖區(qū)被填滿為止。將數(shù)據(jù)序
40、列化到存檔時,存檔積累數(shù)據(jù),直到其緩沖區(qū)被填滿為止。然后,存檔將其緩沖區(qū)寫入然后,存檔將其緩沖區(qū)寫入 CArchive 對象對象ar指向的指向的 CFile 對象。對象。 CFile代表一個磁盤文件,也可以是一個內(nèi)存文件或剪貼板代表一個磁盤文件,也可以是一個內(nèi)存文件或剪貼板第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)3調(diào)用調(diào)用Serialize函數(shù)函數(shù)(1) 建立或者打開文檔流程圖建立或者打開文檔流程圖 OnNewDocument ()OnOpenDocument ()DeleteContents ()SetModifiedFlag (FALSE)DeleteContents ()SetModif
41、iedFlag (FALSE)GetFile(.)構(gòu)造CArchive對象Serialize(.)文檔對象可用菜單命令FileNew菜單命令FileOpenCArchive 對對象提供了一個象提供了一個類型安全緩沖類型安全緩沖機制,用于將機制,用于將可序列化對象可序列化對象寫入寫入 CFile 對對象或從中讀取象或從中讀取可序列化對象可序列化對象清空文檔類數(shù)據(jù)清空文檔類數(shù)據(jù)成員,確保消除成員,確保消除以前打開的文檔以前打開的文檔的數(shù)據(jù)被清理掉的數(shù)據(jù)被清理掉用戶如果在視圖的其它任何地方用戶如果在視圖的其它任何地方修改了文檔,也必須調(diào)用修改了文檔,也必須調(diào)用SetModifiedFlag來設置文檔
42、修改來設置文檔修改標記,以便關閉窗口時讓框架提標記,以便關閉窗口時讓框架提示保存文檔示保存文檔把把GetFile()函數(shù)獲得給定文件函數(shù)獲得給定文件的的CFile指針指針構(gòu)造構(gòu)造 CArchive對對象交給象交給Serialize()函數(shù)完成讀文函數(shù)完成讀文件重建文檔對象的工作件重建文檔對象的工作 第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)(2) 保存文檔流程圖保存文檔流程圖 菜單命令FileSave菜單命令FileSave AsOnSaveDocument()DeleteContents ()SetModifiedFlag (FALSE)Serialize (.)文件保存命令完成GetFile
43、 (.)構(gòu)造CArchive對象將數(shù)據(jù)序列化到存檔時,將數(shù)據(jù)序列化到存檔時,存檔積累數(shù)據(jù),直到其存檔積累數(shù)據(jù),直到其緩沖區(qū)被填滿為止。然緩沖區(qū)被填滿為止。然后,存檔將其緩沖區(qū)寫后,存檔將其緩沖區(qū)寫入入 CArchive 對象指向?qū)ο笾赶虻牡?CFile 對象。對象。 同樣,當從存檔中讀取數(shù)據(jù)同樣,當從存檔中讀取數(shù)據(jù)時,存檔會將數(shù)據(jù)從文件讀取到時,存檔會將數(shù)據(jù)從文件讀取到它的緩沖區(qū),然后從緩沖區(qū)讀取它的緩沖區(qū),然后從緩沖區(qū)讀取到反序列化的對象。到反序列化的對象。這種緩沖減這種緩沖減少了物理讀取硬盤的次數(shù),從而少了物理讀取硬盤的次數(shù),從而提高了應用程序的性能。提高了應用程序的性能。 CArchiv
44、e使用緩沖區(qū)作為臨使用緩沖區(qū)作為臨時數(shù)據(jù)存儲地,讀寫都先依次排時數(shù)據(jù)存儲地,讀寫都先依次排列到此緩沖區(qū),當緩沖區(qū)滿或用列到此緩沖區(qū),當緩沖區(qū)滿或用戶要求時,將此段整理后的數(shù)據(jù)戶要求時,將此段整理后的數(shù)據(jù)讀寫到指定的存儲介質(zhì)。讀寫到指定的存儲介質(zhì)。 好比火車貨場裝運零散的貨好比火車貨場裝運零散的貨物被收集,當總量到達火車運量物被收集,當總量到達火車運量的時候,由火車裝運走。的時候,由火車裝運走。如果用戶執(zhí)行了如果用戶執(zhí)行了Save或或Save As操作,則將文檔的修改標操作,則將文檔的修改標志置為假。這樣,當用戶關閉文檔的最后一個視圖時,志置為假。這樣,當用戶關閉文檔的最后一個視圖時,框架根據(jù)該
45、修改標記決定是否提示用戶保存文檔中的數(shù)框架根據(jù)該修改標記決定是否提示用戶保存文檔中的數(shù)據(jù)到文件。如果用戶上次作了修改還沒有存盤,則彈出據(jù)到文件。如果用戶上次作了修改還沒有存盤,則彈出一個消息框,提示是否保存文件。一個消息框,提示是否保存文件。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.3 視圖類視圖類第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.3.1 視圖類的結(jié)構(gòu)及其方法視圖類的結(jié)構(gòu)及其方法1視圖類的結(jié)構(gòu)視圖類的結(jié)構(gòu)視圖類具有視圖類具有CWnd的所有功能,如:創(chuàng)建、移動、顯示和隱的所有功能,如:創(chuàng)建、移動、顯示和隱藏窗口等。藏窗口等。CView類可以接收任何類可以接收任何Windows消息
46、,而消息,而CDocument類則不行類則不行 第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.3.1 視圖類的結(jié)構(gòu)及其方法視圖類的結(jié)構(gòu)及其方法2視圖類的方法視圖類的方法(1)CView中的一般方法中的一般方法(2)虛擬方法)虛擬方法方方 法法 說說 明明 GetDocument() DoPreparePrinting() 獲獲得得指指向向與與視視圖圖相相關關聯(lián)聯(lián)的的文文檔檔的的指指針針 初初始始化化視視圖圖窗窗口口 第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)視圖類常用方法視圖類常用方法 一個視圖類可以通過一個視圖類可以通過GetDocument( )函數(shù)得到和它關聯(lián)的文函數(shù)得到和它關聯(lián)的文檔的指
47、針,進一步可以得到文檔中保存的數(shù)據(jù)。檔的指針,進一步可以得到文檔中保存的數(shù)據(jù)。 當一個文檔對象的數(shù)據(jù)發(fā)生變化時,該文檔對象可以通過調(diào)當一個文檔對象的數(shù)據(jù)發(fā)生變化時,該文檔對象可以通過調(diào)用成員函數(shù)用成員函數(shù)UpdateAllView( )作出響應,刷新所有的視圖,作出響應,刷新所有的視圖,這個函數(shù)是維護數(shù)據(jù)正確顯示的常用手段。這個函數(shù)是維護數(shù)據(jù)正確顯示的常用手段。 CView類中最常用的是類中最常用的是OnDraw函數(shù),該函數(shù)在屏幕發(fā)生變函數(shù),該函數(shù)在屏幕發(fā)生變化或因為焦點的變化需要重繪時調(diào)用,沒有該函數(shù),就不可化或因為焦點的變化需要重繪時調(diào)用,沒有該函數(shù),就不可能在程序的切換后保證屏幕的正確顯
48、示。能在程序的切換后保證屏幕的正確顯示。 盡量不要在盡量不要在OnDraw之外的函數(shù)調(diào)用繪圖方法,那些方法不之外的函數(shù)調(diào)用繪圖方法,那些方法不會在視圖需要重新繪制的時候被自動調(diào)用。會在視圖需要重新繪制的時候被自動調(diào)用。 若想在數(shù)據(jù)更新若想在數(shù)據(jù)更新的時強制視圖更新,可調(diào)用的時強制視圖更新,可調(diào)用Invalidate方法和方法和UpdateWindow方法來實現(xiàn)。方法來實現(xiàn)。 第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.3.2 視圖類的派生類視圖類的派生類1.CEditView支持類似編輯控件所要實現(xiàn)的功能,常見的文本支持類似編輯控件所要實現(xiàn)的功能,常見的文本操作,基本上都是由該類支持實現(xiàn)的。
49、值得注意操作,基本上都是由該類支持實現(xiàn)的。值得注意的是,該類的直接基類不是的是,該類的直接基類不是CView類,而是類類,而是類CCtrlView2.CRichEditView主要提供主要提供Rich文本操作的支持(文本操作的支持(Rich文本是既可文本是既可以為文本,也可以為圖形的一種特殊格式文本)以為文本,也可以為圖形的一種特殊格式文本)3.CTreeView主要提供一些樹型控件所實現(xiàn)的功能的支持。它主要提供一些樹型控件所實現(xiàn)的功能的支持。它使一種數(shù)據(jù)的顯示方式可以更富于變化。使一種數(shù)據(jù)的顯示方式可以更富于變化。4. CListView該類與類該類與類CTreeView一樣,更多的好處在于
50、提供一樣,更多的好處在于提供了一種簡捷地實現(xiàn)數(shù)據(jù)的不同顯示的途徑了一種簡捷地實現(xiàn)數(shù)據(jù)的不同顯示的途徑5.CScrollView它主要提供視圖的滾動顯示。需要注意的是,該它主要提供視圖的滾動顯示。需要注意的是,該類的直接基類是類的直接基類是CView類類第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)11.4 文檔文檔/視圖結(jié)構(gòu)應用實例視圖結(jié)構(gòu)應用實例例例11-1 創(chuàng)建一個創(chuàng)建一個單文檔單文檔應用程序,在應用程序的主窗口中應用程序,在應用程序的主窗口中顯示一行文本顯示一行文本“Welcome to SDI!”。在。在“編輯編輯”菜單上菜單上有一個有一個菜單項菜單項“改變顯示文本改變顯示文本”,單擊該項可
51、以彈出一,單擊該項可以彈出一個對話框,通過這個個對話框,通過這個對話框?qū)υ捒蚩梢愿淖冎鞔翱谥械娘@示文可以改變主窗口中的顯示文本。本。 第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)(1) 創(chuàng)建項目文件創(chuàng)建項目文件(2) 添加資源。添加資源。為程序添加如圖為程序添加如圖11-4所示的所示的Input對話框,對話框,ID值為值為IDC_INPUT_DIALOG。然后使用。然后使用ClassWizard為對話框為對話框新生成新生成一個一個CDialog類的派生類類的派生類CInputDlg第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)為其中為其中IDC_INPUT_EDIT的編輯框控件添加相關聯(lián)的成員的編輯框控
52、件添加相關聯(lián)的成員變量變量m_Input。(3) 為為CInputDlg添加成員變量添加成員變量m_StrID變量名稱變量名稱變量類型變量類型IDC_INPUT_EDITm_InputCString在在CMySdiDoc的定義中:的定義中:class CMySdiDoc : public CDocument / Attributespublic:CString m_Str;/添加成員變量添加成員變量第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)(4) 文檔變量初始化文檔變量初始化BOOL CMySdiDoc:OnNewDocument()if (!CDocument:OnNewDocument()r
53、eturn FALSE;/ TODO: add reinitialization code herem_Str=Welcome to SDI!; /初始化文檔變量初始化文檔變量/ (SDI documents will reuse this document)return TRUE;第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)(5) 視圖的輸出視圖的輸出-在客戶區(qū)的在客戶區(qū)的固定固定位置顯示字符串位置顯示字符串void CMySdiView:OnDraw(CDC* pDC) CMysdiDoc* pDoc = GetDocument(); /獲取與視圖關聯(lián)的文檔獲取與視圖關聯(lián)的文檔ASSERT_V
54、ALID(pDoc);/ TODO: add draw code for native data hereCString str=pDoc-m_Str;pDC-TextOut(10,10,str);第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)(5) 視圖的輸出視圖的輸出-在客戶區(qū)的居中位置顯示字符串在客戶區(qū)的居中位置顯示字符串void CMySdiView:OnDraw(CDC* pDC) CMySdiDoc* pDoc = GetDocument(); /獲取與視圖關聯(lián)的文檔獲取與視圖關聯(lián)的文檔 ASSERT_VALID(pDoc); CRect rectClient; GetClientRec
55、t(&rectClient); /獲取窗口客戶區(qū)的坐標獲取窗口客戶區(qū)的坐標 CString str=pDoc-m_Str;/ / 從文件中讀取數(shù)據(jù)從文件中讀取數(shù)據(jù) CSize sizeTextExtent=pDC-GetTextExtent(str); /獲取字符串大小獲取字符串大小/ / 用新選定的字體繪制字符串,在客戶區(qū)的居中位置顯示字符串用新選定的字體繪制字符串,在客戶區(qū)的居中位置顯示字符串 pDC-SetTextColor(RGB(255,0,0); pDC-TextOut(rectClient.right-sizeTextExtent.cx)/2,(rectClient.bo
56、ttom-sizeTextExtent.cy)/2,str); 第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)(6) 文檔串行化文檔串行化 讀文件和寫文件都是必要的數(shù)據(jù)的管理操作,文件存取操讀文件和寫文件都是必要的數(shù)據(jù)的管理操作,文件存取操作稱為作稱為Serialization,由,由Serialize函數(shù)負責。函數(shù)負責。 通過在通過在CMySdiDoc中改寫中改寫Serialize函數(shù)實現(xiàn)函數(shù)實現(xiàn)。第第11章章 文檔文檔/視圖結(jié)構(gòu)視圖結(jié)構(gòu)(6) 文檔串行化文檔串行化 單擊單擊 Workspace窗口中的窗口中的ResourceView選項卡,展開選項卡,展開Mysdi resource | Menu,雙擊,雙擊IDR_MAINFRAME,為,為“編輯編輯”菜單添加一個菜單添加一個菜單項菜單項“改變顯
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度體育賽事贊助與品牌推廣合作協(xié)議4篇
- 二零二五年度停車場充電站建設承包協(xié)議4篇
- 二零二四年校企合作產(chǎn)學研合作成果推廣協(xié)議3篇
- 二零二五年度桉樹苗木種植基地農(nóng)業(yè)保險合作協(xié)議3篇
- 2025年度國際物流樞紐承包合作經(jīng)營協(xié)議書4篇
- 二零二五年度戶外商業(yè)街攤位使用權(quán)轉(zhuǎn)讓與推廣合同3篇
- 二零二四年美容產(chǎn)品線上線下聯(lián)合銷售合同3篇
- 2025年柴油期貨交易合同范本(金融衍生品)4篇
- 專業(yè)快遞發(fā)送合同:2024年度快遞服務合同一
- 二零二五年度智能家居瓷磚安裝工程承包合同4篇
- 常用藥物作用及副作用課件
- 小學生作文方格紙A4紙直接打印版
- 幼兒阿拉伯數(shù)字描紅(0-100)打印版
- 社會組織等級評估報告模板
- GB/T 12173-2008礦用一般型電氣設備
- 2023年1月浙江高考英語聽力試題及答案(含MP3+錄音原文)
- 【課件】第三課 蒙娜麗莎 課件高中美術湘美版美術鑒賞
- 新媒體研究方法教學ppt課件(完整版)
- 東芝空調(diào)維修故障代碼匯總
- 工藝管道儀表流程圖(共68頁).ppt
- 五項管理行動日志excel表格
評論
0/150
提交評論