文檔與視圖.doc_第1頁(yè)
文檔與視圖.doc_第2頁(yè)
文檔與視圖.doc_第3頁(yè)
文檔與視圖.doc_第4頁(yè)
文檔與視圖.doc_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第八章 文檔和視圖學(xué)前提示文檔和視圖結(jié)構(gòu)是 MFC 的一大特色,將數(shù)據(jù)的管理和顯示隔離,文檔對(duì)象是用來(lái)保護(hù)數(shù)據(jù)的,而視圖對(duì)象則是用來(lái)顯示數(shù)據(jù)的,并且允許對(duì)數(shù)據(jù)進(jìn)行編輯。知識(shí)要點(diǎn)文檔和視圖之間的相互作用函數(shù)簡(jiǎn)單文檔視圖應(yīng)用程序文檔的讀寫(xiě)一檔多視8.1 文檔和視圖之間相互作用的函數(shù)文檔對(duì)象是用來(lái)保存數(shù)據(jù)的,視圖對(duì)象是用來(lái)顯示數(shù)據(jù)的,并且允許對(duì)數(shù)據(jù)進(jìn)行編輯。在文檔,視圖和應(yīng)用程序框架之間包含了一系列非常復(fù)雜的相互作用過(guò)程,為了了解這一過(guò)程,這里首先學(xué)習(xí)有關(guān)文檔類(lèi)和視圖類(lèi)的幾個(gè)非常重要的成員函數(shù),其中有的為虛函數(shù),用戶(hù)經(jīng)常需要在派生類(lèi)中對(duì)它們進(jìn)行重載,而有的不是虛函數(shù),經(jīng)常需要在派生類(lèi)中對(duì)它們進(jìn)行調(diào)用。8.1.1 視圖類(lèi)的 GetDocument()函數(shù)視圖對(duì)象只有一個(gè)與之相聯(lián)系的文檔對(duì)象,它所包含的 GetDocument()函數(shù)允許應(yīng)用程序在視圖中得到與之相聯(lián)系的文檔。GetDocument()返回的是指向文檔的指針,利用這個(gè)指針就可以訪(fǎng)問(wèn)文檔類(lèi)或其派生類(lèi)的成員函數(shù)及公有數(shù)據(jù)成員。 當(dāng) Class Wizard產(chǎn)生 CView 的派生類(lèi)時(shí),它同時(shí)也創(chuàng)建一個(gè)保護(hù)類(lèi)型的 GetDocument() 函數(shù),它返回的是指向文檔的指針CMyDoc * CMyView:GetDocument() Return (CMyDoc*)m_pDocument; CDocument 類(lèi)的GetNextView()成員函數(shù)用來(lái)在文檔中得到指向視圖列表的指針,文檔對(duì)象通過(guò)這個(gè)指針遍歷視圖列表,對(duì)每個(gè)視圖都調(diào)用一次該函數(shù)。這時(shí)常用到 CDocument類(lèi)的成員函數(shù) GetFirstViewPosition()和 GetNextView(),其中 GetFirstViewPosition()返回文檔視圖列表中第一個(gè)視圖的POSITION值,而GetNextView()返回下一個(gè)視圖。程序通常類(lèi)似如下的形式;CMyDoc *pDoc; /CMyDoc 為 CDocument 的派生類(lèi)CMyView *pMyView; /CMyView 為 CView 的派生類(lèi)pMyDoc =pMyView-GetDocument();POSITION pos =pMyDoc-GetFirstViewPosition();while(pos !=NULL) pView =(CMyView *)pMyDoc-GetNextView();/對(duì)視圖做相應(yīng)的操作8.1.2 視圖類(lèi)的 OnUpdate()函數(shù) OnUpdate()函數(shù)是一個(gè)虛函數(shù),當(dāng)應(yīng)用程序調(diào)用了 UpdateAllViews()函數(shù)時(shí),應(yīng)用程序框架就會(huì)相應(yīng)地調(diào)用所有視圖的 OnUpdate()函數(shù),當(dāng)然,也可以直接在派生類(lèi)中調(diào)用它。通常視圖派生類(lèi)的 OnUpdate()函數(shù)訪(fǎng)問(wèn)文檔,讀取數(shù)據(jù),對(duì)視圖的數(shù)據(jù)成員或控制進(jìn)行更新。另外,還可以利用 OnUpdate()函數(shù)使視圖的某部分無(wú)效,觸發(fā)視圖的 OnDraw()函數(shù),利用文檔數(shù)據(jù)來(lái)重新繪制窗口。 OnUpdate()函數(shù)類(lèi)似于下面的形式 void CMyView:OnUpdate(CView *pSender,LPARAM lHint,CObject *pHint)CMyDoc *pDoc = GetDocment();ASSERT_VALID(pDoc);/加入視圖的初始代碼其中的提示信息是 UpdateAllViews()函數(shù)直接傳遞過(guò)來(lái)的。默認(rèn)的OnUpdate()函數(shù)使整個(gè)窗口無(wú)效,我們可以重寫(xiě)該函數(shù),利用提示信息來(lái)定義一個(gè)較小的無(wú)效區(qū)域當(dāng)CDocument de OnUpdateAllView()函數(shù)被調(diào)用時(shí),如果pSender參數(shù)指向某個(gè)特定的視圖,那么除了該指定的視圖,文檔所有其他視圖的OnUpdate()函數(shù)都會(huì)被調(diào)用 8.1.3 視圖類(lèi)的 OnInitialUpdate()函數(shù)當(dāng)應(yīng)用程序被啟動(dòng)后,或當(dāng)用戶(hù)從File菜單中選擇了New或 Open命令時(shí),CView的OnInitialUpdate()函數(shù)會(huì)被調(diào)用,該函數(shù)是虛函數(shù),CView的OnInitialUpdate()函數(shù)除了調(diào)用 OnUpdate()函數(shù)之外,不做其他任何事情用戶(hù)也可以利用派生類(lèi)的OnInitialUpdate()函數(shù)對(duì)視圖進(jìn)行初始化。當(dāng)應(yīng)用程序啟動(dòng)后,應(yīng)用程序框架在調(diào)用了 OnCreate()函數(shù)后(如果對(duì)OnCreate()函數(shù)后進(jìn)行映射),會(huì)立即調(diào)用OnInitialUpdate()函數(shù)。OnCreate()函數(shù)只能被調(diào)用一次,而OnInitialUpdate()函數(shù)則可以被調(diào)用多次。8.1.4 文檔類(lèi)的 UpdateAllViews()函數(shù) 如果由于某種原因,文檔數(shù)據(jù)發(fā)生了改變,那么所有的視圖都必須被通知到,以便它們能夠?qū)︼@示的數(shù)據(jù)進(jìn)行相應(yīng)的更新。這時(shí)就要用到 CDocument類(lèi)的UpdateAllViews()函數(shù)。如果在文檔派生類(lèi)的成員函數(shù)中調(diào)用UpdateAllViews()函數(shù),那么它的第一個(gè)參數(shù) pSender 應(yīng)為NULL。如果是在視圖派生類(lèi)的成員函數(shù)中被調(diào)用,應(yīng)該以如下方式將 pSender參數(shù)置為當(dāng)前視圖GetDocument()-UpdateAllsView(this);其中。非空參數(shù)使得應(yīng)用程序框架不再通知當(dāng)前視圖,因?yàn)樽x者假定當(dāng)前視圖已經(jīng)自己進(jìn)行了更新。該函數(shù)的原型如下void UpdateAllViews(CView *pSender,LPARAM lHint,CObject *pHint=NULL);其中 lHint和 pHint為提示參數(shù),可以利用它們給視圖提供一些特殊的與應(yīng)用程序有關(guān)的信息,以便視圖能決定哪些部分應(yīng)該更新,這是對(duì)該函數(shù)的更高級(jí)的用法提示 應(yīng)用程序框架為 CDocument類(lèi)定義了 DeleteContent()虛函數(shù),當(dāng)文檔被關(guān)閉時(shí),應(yīng)用程序框架會(huì)自動(dòng)調(diào)用該函數(shù)。用戶(hù)如果需要對(duì)文檔進(jìn)行清理操作,就可以重寫(xiě)該函數(shù), 8.3 文檔的讀寫(xiě) 用戶(hù)處理的數(shù)據(jù)往往需要存盤(pán)永久備份。將文檔類(lèi)中的數(shù)據(jù)成員變量的值保存在磁盤(pán)文件中,或者將存儲(chǔ)在文檔文件中的數(shù)據(jù)讀取到相應(yīng)的成員變量中。這個(gè)讀寫(xiě)過(guò)程稱(chēng)為文檔序列化(Serialize)8.3.1 MFC 文檔讀寫(xiě)機(jī)制 使用MFC文檔應(yīng)用程序結(jié)構(gòu)可以很簡(jiǎn)單地進(jìn)行文檔讀寫(xiě)操作,下面首先介紹對(duì)文檔進(jìn)行不同操作后,MFC程序的具體運(yùn)行過(guò)程(1) 創(chuàng)建空文檔對(duì)于文檔應(yīng)用程序來(lái)說(shuō),在運(yùn)行到應(yīng)用程序類(lèi)的 InitInstance()函數(shù)時(shí),它會(huì)在調(diào)用了 AddDocTemplate()函數(shù)之后,通過(guò)CWinApp:ProcessShellCommand()間接調(diào)用 CWinApp的另一個(gè)非常有用的成員函數(shù) OnFileNew,并以此完成下列工作(1) 構(gòu)造文檔對(duì)象,但并不從磁盤(pán)中讀數(shù)據(jù)(2) 構(gòu)造主框架窗口類(lèi)CMainFrame的對(duì)象,并創(chuàng)建該主框架窗口,但不顯示(3) 構(gòu)造視圖對(duì)象,并創(chuàng)建視圖窗口,也不顯示(4) 通過(guò)內(nèi)部機(jī)制,使文檔,主框架和視圖“對(duì)象”之間“真正”建立聯(lián)系。注意與 AddDocTemplate()函數(shù)的區(qū)別,AddDocTemplate()函數(shù)建立的是“類(lèi)”之間的聯(lián)系。(5) 調(diào)用文檔對(duì)象的 CDocument:OnNewDocument()函數(shù),該函數(shù)將首先調(diào)用CDocument:DeleteContents()虛函數(shù)清除文檔對(duì)象的內(nèi)容,然后調(diào)用SetModifiedFlag(FALSE)將文檔修改標(biāo)志清除。菜單命令 File New菜單命令 File OpenSetModifiedFlag(FALSE)GetFile() 構(gòu)造CArchive 對(duì)象DeleteContents()DeleteContents()Serialize()SetModifiedFlag(FALSE)文檔對(duì)象可用 OnNewDocument() OnOpenDocument() 建立與打開(kāi)文檔(6) 調(diào)用視圖對(duì)象的CView:OnInitialUpdate()虛函數(shù)對(duì)視圖進(jìn)行初始化操作(7) 調(diào)用框架對(duì)象的 CFramWnd:ActiveFram()虛函數(shù),以便顯示出帶有菜單,工具欄,狀態(tài)欄以及視圖窗口的主框架窗口。說(shuō)明在當(dāng)文檔應(yīng)用程序中,文檔,主框架以及視圖對(duì)象僅被創(chuàng)建一次,并且這些對(duì)象在整個(gè)運(yùn)行過(guò)程中都有效。CWinApp:OnFileNew()函數(shù)被 InitInstance()函數(shù)所調(diào)用,但當(dāng)用戶(hù)選擇“文件”菜單的“新建”命令時(shí)。CWinApp:OnFileNew()也會(huì)被調(diào)用,與InitInstance()不同的是。這種情況下不存在創(chuàng)建文檔,主框架以及視圖對(duì)象,但上述過(guò)程的最后3個(gè)步驟仍然會(huì)被執(zhí)行(2) 打開(kāi)文檔 當(dāng)MFC AppWizard創(chuàng)建文檔應(yīng)用程序時(shí),它會(huì)自動(dòng)將“文件“命令(ID號(hào)為 ID_FILE_OPEN)映射到CWinApp的OnFileOpen()成員函數(shù)。這一結(jié)果可以從應(yīng)用類(lèi)(。Cpp)的消息入口處得到驗(yàn)證OnFileOpen()函數(shù)還會(huì)進(jìn)一步完成下列工作、(1) 彈出通用的“打開(kāi)“文件對(duì)話(huà)框,供用戶(hù)選擇一個(gè)文檔(2) 文檔指定后,調(diào)用文檔對(duì)象的CDocument:OnOPenDocument()虛函數(shù)。該虛函數(shù)將首先調(diào)用GetFile()獲得給定文件的 CFile 指針,在調(diào)用DeleteContents()清除文檔對(duì)象的內(nèi)容,然后用CFile指針創(chuàng)建一個(gè)CArchive 對(duì)對(duì)象交給Serialize函數(shù)完成讀文件重建文檔對(duì)象的工作,最后在調(diào)用SetModifiedFlag(FALSE)將文檔修改標(biāo)志清除(3) 調(diào)用視圖對(duì)象的CView:OnInitialUpdate()虛函數(shù) 除了使用“文件“菜單中”打開(kāi)“命令外,用戶(hù)也可以選擇最近使用過(guò)的文件列表來(lái)打開(kāi)相應(yīng)的文檔。在應(yīng)用程序的運(yùn)行過(guò)程中,系統(tǒng)會(huì)記錄4個(gè)(默認(rèn))最近使用過(guò)的文件,并將文件名保存在Windows的注冊(cè)表中。當(dāng)每次啟動(dòng)應(yīng)用程序時(shí),應(yīng)用程序都會(huì)把最近使用過(guò)的文件名稱(chēng)顯示在”文件“菜單中。(3)保存文檔當(dāng)MFC AppWizard創(chuàng)建應(yīng)用程序時(shí),它會(huì)自動(dòng)將“文件(file)“菜單中”保存“命令與文檔類(lèi) CDocument 的OnFileSave函數(shù)還會(huì)進(jìn)一步完成下列工作(1) 彈出通用的“保存“文件對(duì)話(huà)框,讓用戶(hù)提供一個(gè)文件名(2) 調(diào)用文檔對(duì)象的 CDocument:OnsaveDocument()虛函數(shù),該函數(shù)將首先詢(xún)問(wèn)文件的名字,調(diào)用GetFile()獲得給定文件的CFile指針,然后用CFile 指針創(chuàng)建一個(gè)CArchive對(duì)象交給Serialize 函數(shù)完成寫(xiě)文件的工作,最后再調(diào)用SetModifiedFlag(FALSE)將文檔修改標(biāo)志清除。菜單命令 File Sava菜單命令 File SavaAsGetFile()構(gòu)造CArchive對(duì)象Serialize()SetModifiedFlag(FALSE)文件保存命令完成 OnSaveDocument() ) 保存文檔 保存文檔說(shuō)明只有在保存文檔之前還沒(méi)有存過(guò)盤(pán)(亦即沒(méi)有文件名)或讀取的文檔是“只讀“的OnFileSave函數(shù)才會(huì)彈出通用的“保存“文件對(duì)話(huà)框。否則,只執(zhí)行第二步在“文件”菜單中還有一個(gè)“另存為”命令,它是與文檔類(lèi)CDocument 的 OnFileSaveAs()函數(shù)相關(guān)聯(lián)。不管文檔有沒(méi)有保存過(guò),OnFileSaveAs()都會(huì)執(zhí)行上述兩個(gè)步驟 上述將文檔存盤(pán)的必要操作都是由系統(tǒng)自動(dòng)完成的。(4)關(guān)閉文檔當(dāng)用戶(hù)試圖關(guān)閉文檔(或 退出應(yīng)用程序)時(shí),應(yīng)用程序會(huì)根據(jù)用戶(hù)對(duì)文檔的修改與否來(lái)進(jìn)一步完成下列任務(wù)(1)若文檔內(nèi)容已被修改,則彈出一個(gè)消息對(duì)話(huà)框,詢(xún)問(wèn)用戶(hù)是否需要將文檔保存,若用戶(hù)選擇“是”,則應(yīng)用程序執(zhí)行 OnFileSave()過(guò)程(2)調(diào)用 CDocument:OnCloseDocument()虛函數(shù),關(guān)閉所有與該文檔相關(guān)聯(lián)的文檔窗口及相應(yīng)的視圖,調(diào)用文檔類(lèi)CDocument的DeleteContents()清除文檔數(shù)據(jù)說(shuō)明MFC應(yīng)用程序通過(guò) CDocument 的protected類(lèi)型成員變量m_bModified的邏輯值;來(lái)判斷程序員是否對(duì)文檔進(jìn)行了修改,若m_bModified 為“真”,則表示文檔被修改。對(duì)于程序員來(lái)說(shuō),可以通過(guò)CDocument的SetModifiedFlag()成員函數(shù)或通過(guò)IsModified()成員函數(shù)來(lái)訪(fǎng)問(wèn)Modifie的邏輯值,當(dāng)文件創(chuàng)建,從磁盤(pán)中讀出以及存盤(pán)時(shí),文檔的這個(gè)標(biāo)記就被置為FALSE(假),而當(dāng)文檔數(shù)據(jù)被修改時(shí),程序員必須用 SetModifiedFlag()函數(shù)將該標(biāo)記置為T(mén)RUE。這樣,當(dāng)用戶(hù)關(guān)閉文檔時(shí),應(yīng)用程序才會(huì)顯示詢(xún)問(wèn)消息對(duì)話(huà)框。由于多文檔應(yīng)用程序序列化過(guò)程基本上和單文檔相似,因此這里無(wú)需重復(fù)(5)文檔讀寫(xiě)操作從上述的單文檔序列化過(guò)程可以看出,在打開(kāi)文檔和保存文檔時(shí),系統(tǒng)會(huì)都會(huì)主動(dòng)調(diào)用 Seriallize函數(shù),事實(shí)上,MFC AppWizard 在創(chuàng)建文檔應(yīng)用程序時(shí)已在文檔類(lèi)中重載了Serialize函數(shù),通過(guò)在該函數(shù)中添加代碼可以達(dá)到實(shí)現(xiàn)數(shù)據(jù)序列化的目的。 如在 Ex_XXX 單文檔應(yīng)用程序的文檔類(lèi)中有這樣的默認(rèn)代碼void CE_XXXDoc:Serialize(CArchive &ar)if(ar.IsStoring() /當(dāng)文檔數(shù)據(jù)需要存盤(pán)時(shí)else /當(dāng)文檔數(shù)據(jù)需要讀取時(shí)其中,Serialize函數(shù)的參數(shù) ar是一個(gè)CArchive類(lèi)引用變量。通過(guò)判斷 ar.IsStoring的結(jié)果是“真”,還是“假”就可以決定文檔寫(xiě)或讀數(shù)據(jù)CArchive(歸檔)類(lèi)提供對(duì)文件數(shù)據(jù)進(jìn)行緩存,它同時(shí)還保存一個(gè)內(nèi)部標(biāo)記,用來(lái)標(biāo)識(shí)文檔是存入(寫(xiě)盤(pán))還是載入(讀盤(pán))。每次只能有一個(gè)活動(dòng)的存檔與ar相連。通過(guò) CArchive類(lèi)就可以簡(jiǎn)化文件操作,它提供“”運(yùn)算符,用于向文件寫(xiě)入簡(jiǎn)單的數(shù)據(jù)類(lèi)型以及從文件中讀取它們8.4 切分窗口 切分窗口是一種“特殊“的文檔窗口,它可有有許多窗格,在窗格中又可包含若干個(gè)視圖8.4.1 CSplitterWnd類(lèi)操作在MFC中CSplitterWnd類(lèi)封裝了窗口切分過(guò)程中所需要的功能函數(shù),其中成員函數(shù)Create和CreateStatic分別用來(lái)創(chuàng)建“動(dòng)態(tài)切分”和靜態(tài)“切分”的文檔窗口,具體函數(shù)原型如下virtual BOOL Create( CWnd* pParentWnd, int nMaxRows, int nMaxCols, SIZE sizeMin, CCreateContext* pContext, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | SPLS_DYNAMIC_SPLIT, UINT nID = AFX_IDW_PANE_FIRST );virt

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論