VisualC程序設(shè)計(jì)教程第七章框架窗口、和視圖_第1頁(yè)
VisualC程序設(shè)計(jì)教程第七章框架窗口、和視圖_第2頁(yè)
VisualC程序設(shè)計(jì)教程第七章框架窗口、和視圖_第3頁(yè)
VisualC程序設(shè)計(jì)教程第七章框架窗口、和視圖_第4頁(yè)
VisualC程序設(shè)計(jì)教程第七章框架窗口、和視圖_第5頁(yè)
已閱讀5頁(yè),還剩75頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第第7章章 框架窗口、文檔和視圖框架窗口、文檔和視圖7.1 應(yīng)用程序組成結(jié)構(gòu)應(yīng)用程序組成結(jié)構(gòu)1單文檔應(yīng)用程序(single document interface,sdi) 在單文檔界面程序中,用戶在同一時(shí)刻只能操作一個(gè)文檔,如記事本程序。在這些應(yīng)用程序中,打開文檔時(shí)會(huì)自動(dòng)關(guān)閉當(dāng)前打開的活動(dòng)文檔,若文檔修改后尚未保存,會(huì)提示是否保存所做的修改。因?yàn)橐淮沃婚_一個(gè)窗口,因此不像word那樣需要一個(gè)窗口菜單。單文檔應(yīng)用程序一般都提供一個(gè)“文件”菜單,在該菜單下有一組命令,用于新建文檔、打開已有文檔、保存或另存為等。這類程序相對(duì)比較簡(jiǎn)單,常見的應(yīng)用程序有終端仿真程序和一些工具程序。n2多文檔應(yīng)用程序(m

2、ultiple document interface,mdi)n 在多文檔界面應(yīng)用程序中,允許同時(shí)操作多個(gè)文檔,如microsoft word??梢源蜷_多個(gè)文件(同時(shí)也就為每個(gè)文件打開一個(gè)窗口),可以通過切換活動(dòng)窗口激活相應(yīng)的文檔進(jìn)行編輯。多文檔應(yīng)用程序也提供一個(gè)“文件”菜單,用于新建、打開、保存文檔。與單文檔應(yīng)用程序不同的是,它往往還提供一個(gè)“關(guān)閉”菜單項(xiàng),用于關(guān)閉當(dāng)前打開的文檔。多文檔應(yīng)用程序還提供一個(gè)“窗口”菜單,管理所有打開的子窗口,包括對(duì)子窗口的新建、關(guān)閉、層疊、平鋪等。關(guān)閉一個(gè)窗口時(shí),窗口內(nèi)的文檔也被自動(dòng)關(guān)閉。n3基于對(duì)話框的應(yīng)用程序(dialog based applicatio

3、n)n 基于對(duì)話框的應(yīng)用程序非常簡(jiǎn)單,由應(yīng)用程序類、對(duì)話框類(可以作為其它控件的容器)構(gòu)成。它的生命周期可概括為:通過應(yīng)用程序類的initinstance()函數(shù),構(gòu)造一個(gè)模式對(duì)話框?qū)ο?;調(diào)用domodal函數(shù),讓基于對(duì)話框的應(yīng)用程序像對(duì)待普通對(duì)話框一樣接收和分配消息;用戶退出對(duì)話框后,程序也就隨之結(jié)束。常見的基于對(duì)話框的應(yīng)用程序有計(jì)算器等(以對(duì)話框?yàn)槿萜鞑季值某绦颍?.1.1 cmainframe類和窗口nmfc應(yīng)用程序主要由3部分組成:窗口、文檔和視圖。其中窗口是整個(gè)應(yīng)用程序的載體,也是應(yīng)用程序不可缺少的部分。n窗口也叫框架窗口,它可以分為兩類:一類是主框架窗口(也叫主窗口),另一類是子

4、框架窗口(也叫子窗口)。在mfc應(yīng)用程序中,框架(framework)是應(yīng)用程序所應(yīng)具備的軟件模塊按一定的結(jié)構(gòu)組成的集合。框架窗口可以理解為框架的可視化顯示形式。n主框架窗口是應(yīng)用程序放置在桌面(desktop)上的那個(gè)窗口,每個(gè)應(yīng)用程序只能有一個(gè)主窗口,主窗口的標(biāo)題欄上通常顯示應(yīng)用程序的名稱。子框架窗口是應(yīng)用程序主框架窗口內(nèi)的子窗口,它占據(jù)了主框架窗口客戶區(qū)的部分或全部。視圖是子框架窗口內(nèi)的子窗口,它占據(jù)了子框架窗口客戶區(qū)的部分或全部。n圖7-1標(biāo)明了多文檔應(yīng)用程序中主框架窗口、子框架窗口和視圖之間的關(guān)系。由于單文檔應(yīng)用程序沒有子框架窗口,所以可以認(rèn)為視圖充滿了整個(gè)主框架窗口。n使用mfc

5、appwizard創(chuàng)建單文檔應(yīng)用程序后,包含主框架窗口類的文件分別為mainfrm.h和mainfrm.cpp。主框架窗口類是由cframewnd派生而來(lái)的,類名為cmainframe。而對(duì)于多文檔應(yīng)用程序,主框架窗口由cmdiframewnd派生。ncmainframe類有4個(gè)重要的函數(shù):assertvalid、dump、oncreate和precreatewindow。這4個(gè)函數(shù)都是由應(yīng)用程序向?qū)ё詣?dòng)聲明和定義的,無(wú)須人為干預(yù),不過了解它們的作用還是非常有必要的,在需要的情況下,用戶還可以修改它們以達(dá)到預(yù)定效果。它們各自的功能如下:n(1)assertvalid 函數(shù)用來(lái)診斷cmainfr

6、ame對(duì)象的有效性。n(2)dump 函數(shù)用來(lái)輸出cmainframe對(duì)象的狀態(tài)信息。n(3)oncreate 函數(shù)用來(lái)創(chuàng)建工具欄m_wndtoolbar和狀態(tài)欄m_wndstatusbar,而在視圖窗口中是由基類cframewnd的成員函數(shù)oncreate通過調(diào)用oncreateclient函數(shù)創(chuàng)建的。n(4)precreatewindow 函數(shù)是一個(gè)虛函數(shù)。如果要?jiǎng)?chuàng)建一個(gè)非默認(rèn)風(fēng)格的窗口,可以重載這個(gè)函數(shù),在函數(shù)中通過修改createstruct結(jié)構(gòu)參數(shù)來(lái)改變窗口類、窗口風(fēng)格、窗口大小和位置等。7.1.2 cdocument類和文檔ncdocument類是ccmdtarget類的派生類,其

7、派生關(guān)系如圖74所示。cdocument類為用戶定義的文檔類提供了基本的函數(shù)功能,它支持標(biāo)準(zhǔn)操作,如創(chuàng)建、裝載、保存等。一個(gè)應(yīng)用程序可以支持多種類型的文檔,每種類型的文檔都通過一個(gè)文檔模板對(duì)象建立與各自視圖的聯(lián)系。n不論是sdi應(yīng)用程序還是mdi應(yīng)用程序,文檔類都是從cdocument類派生出來(lái)的。在文檔/視圖結(jié)構(gòu)中,文檔類的主要任務(wù)通常是對(duì)數(shù)據(jù)進(jìn)行管理和維護(hù),數(shù)據(jù)將保存在文檔類的成員變量中,視圖通過對(duì)這些變量的訪問來(lái)獲取或返回?cái)?shù)據(jù),并能通過這種方式來(lái)更新并顯示數(shù)據(jù)。n從cdocument類派生文檔類的步驟如下:n(1)為每一個(gè)文檔類型從 cdocument類(當(dāng)然也可以是其他 cdocume

8、nt類的派生類)派生一個(gè)相應(yīng)的文檔類。n(2)為文檔類添加成員變量。這些成員變量用來(lái)保存文檔的數(shù)據(jù),其他對(duì)象(如與文檔相關(guān)聯(lián)的視圖)直接或間接地訪問這些成員變量以讀取或更新文檔的數(shù)據(jù)。n(3)重載serialize成員函數(shù),實(shí)現(xiàn)文檔數(shù)據(jù)的序列化。7.1.3 cview類和視圖ncview類是cwnd類的派生類,其派生關(guān)系如圖7-5所示。cview類是mfc中一個(gè)基本的類,也是其他mfc視圖類和用戶視圖派生類的基類。n視圖窗口用來(lái)顯示文檔中的數(shù)據(jù),并根據(jù)視圖對(duì)象提供的基本功能,指定用戶使用什么方式查看文檔數(shù)據(jù),接受用戶對(duì)數(shù)據(jù)的交互操作(包括選擇和編輯),并將更改后的數(shù)據(jù)回傳給文檔。視圖被附加到文

9、檔中并在文檔和用戶之間充當(dāng)媒介,它可以在屏幕上呈現(xiàn)文檔的數(shù)據(jù),并將用戶輸入解釋為對(duì)文檔的操作,還可以為打印和打印預(yù)覽呈現(xiàn)圖像。n在mfc類庫(kù)的層次位置中,cview類是從cwnd類下派生的,掌握這個(gè)繼承關(guān)系對(duì)用戶來(lái)說是很有用的。例如,由于所有的從cview類派生的類也都是由cwnd類間接派生的,因此這些類具有cwnd的所有功能,如創(chuàng)建、移動(dòng)、顯示和隱藏窗口等,并且cview類可以接收任何windows消息。ncview類只提供了基礎(chǔ)框架,在mfc中派生了cview類的許多子類,為不同的應(yīng)用提供了強(qiáng)大支持。這些視圖類都不是直接派生于cview類,而是派生于cview的子類cctrlview。cc

10、trlview類的派生類對(duì)應(yīng)于windows通用控件,提供了與通用控件相對(duì)應(yīng)的功能。下面簡(jiǎn)單地介紹一下視圖類各派生類的情況。n1.ceditview 類nceditview類主要用來(lái)支持類似編輯控件所要實(shí)現(xiàn)的功能,常見的文本操作基本上都是由該類支持實(shí)現(xiàn)的。n如果希望有一個(gè)具有簡(jiǎn)單編輯功能或附加功能的編輯窗口,就可以構(gòu)造一個(gè)ceditview類型的對(duì)象。一個(gè)ceditview對(duì)象可以占有一個(gè)窗體的整個(gè)用戶區(qū)。用戶也可以通過從ceditview中派生自己的類來(lái)增加或改變基本功能,并可以聲明能加入到文檔模板中的類。n2.ctreeview 類nctreeview類主要提供對(duì)一些樹形控件所實(shí)現(xiàn)的功能的

11、支持。它可以使數(shù)據(jù)的顯示方式更富于變化。n3.clistview 類nclistview類與ctreeview類類似,不同之處在于它提供了一種簡(jiǎn)捷地實(shí)現(xiàn)數(shù)據(jù)的不同顯示方式的途徑,為數(shù)據(jù)組織提供了多種手段。n4.cricheditview 類ncricheditview類主要提供對(duì)rich文本操作的支持。rich文本是既可以為文本,也可以為圖形圖像的一種特殊格式的文本。n5.cscrollview 類ncscrollview類的主要功能是提供視圖的滾動(dòng)顯示。需要注意的是,以上介紹的幾個(gè)類都是間接派生于cview類,而該類直接繼承至cview類,這就決定了其動(dòng)作的特殊性。7.1.4 框架窗口、文檔

12、和視圖的關(guān)系n文檔/視圖結(jié)構(gòu)是mfc應(yīng)用程序中最基本的程序結(jié)構(gòu),它適用于大多數(shù)windows應(yīng)用程序。文檔與視圖完成了程序的大部分功能,它們是mfc應(yīng)用程序的核心。n由mfc創(chuàng)建的應(yīng)用程序的主線程序體現(xiàn)在應(yīng)用類中,而應(yīng)用類通過文檔模板類將文檔類、窗口類(sdi中的主窗口類或mdi中的子窗口類)、視圖類聯(lián)系在一起,組成一個(gè)有機(jī)整體,共同完成程序設(shè)計(jì)任務(wù)。單文檔模板類csingledoctemplate和多文檔模板類cmutidoctemplate均由cdoctemplate類派生。單文檔模板類支持單文檔應(yīng)用程序,多文檔模板類支持多文檔應(yīng)用程序。n應(yīng)用類cwinapp通過一個(gè)內(nèi)部類cdocmana

13、ger來(lái)管理文檔模板類。cwinapp類成員變量m_pdocmanager是指向cdocmanager類對(duì)象的指針。在cdocmanager類中定義的指針鏈表,其每項(xiàng)都是一個(gè)指向文檔模板對(duì)象的指針。實(shí)際上,應(yīng)用類通過其鏈表成員管理應(yīng)用程序的所有文檔模板對(duì)象。n文檔對(duì)象用來(lái)保存和管理數(shù)據(jù),視圖對(duì)象用于數(shù)據(jù)交互,應(yīng)用程序框架用來(lái)管理不同文檔顯示界面。例如,程序設(shè)計(jì)要求用數(shù)據(jù)網(wǎng)格顯示二維數(shù)據(jù),同時(shí)還要求用圖形顯示二維數(shù)據(jù),即這些數(shù)據(jù)來(lái)自同一文檔,但以不同的視圖方式顯示。在這種情況下可以用框架中的文檔模板把一個(gè)文檔及兩個(gè)視圖組合在一起。n在程序運(yùn)行時(shí),cwinapp將創(chuàng)建一個(gè)cframewnd框架窗口

14、實(shí)例,而框架窗口將創(chuàng)建文檔模板,然后由文檔模板創(chuàng)建文檔實(shí)例和視圖實(shí)例,并將兩者關(guān)聯(lián)起來(lái)。一般來(lái)講,用戶只需對(duì)文檔和視圖進(jìn)行操作,框架的各種行為已經(jīng)被mfc安排好而不需要人為干預(yù),這也是mfc設(shè)計(jì)文檔/視圖結(jié)構(gòu)的本意,讓用戶將注意力放在完成任務(wù)上,而從界面編寫中解放出來(lái)。文檔/視圖結(jié)構(gòu)的數(shù)據(jù)交互如圖7-6所示,兩者的關(guān)系如圖7-7所示。圖7-6 文檔-視圖結(jié)構(gòu)的數(shù)據(jù)交互圖7-7 文檔與視圖的關(guān)系 n框架窗口、文檔和視圖之間的關(guān)系可以表述為:文檔和視圖之間是一對(duì)多的關(guān)系,每個(gè)視圖和框架窗口是一對(duì)一的關(guān)系。n框架窗口、文檔和視圖三者之間是相互關(guān)聯(lián)、相互協(xié)調(diào)的,彼此都包含了指向?qū)Ψ降闹羔?。它們之間的聯(lián)

15、系是通過文檔模板的構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)的。下面介紹在程序中如何得到各種對(duì)象的指針。n(1)全局函數(shù)afxgetapp()可以得到cwinapp應(yīng)用程序類指針,而afxgetapp()-m_pmainwnd就是框架窗口cframewnd的指針。n(2)在框架窗口中,cframewnd:getactivedocument()得到當(dāng)前活動(dòng)文檔指針。n(3)在框架窗口中,cframewnd:getactiveview()得到當(dāng)前活動(dòng)視圖指針。n(4)在視圖中,cview:getdocument()用于檢索指向文檔類的指針。n(5)在文檔中,cdocument:getfirstviewposition()和c

16、document:getnextview()用來(lái)遍歷所有和文檔關(guān)聯(lián)的視圖。n(6)在文檔中,cdocument:getdoctemplate()用來(lái)得到文檔模板指針。n(7)在多文檔界面中,cmdiframewnd:mdigetactive()得到當(dāng)前活動(dòng)的mdi子窗口。7.2 文檔n文檔(document)是mfc應(yīng)用程序中所處理數(shù)據(jù)的集合,包括文本、圖形、圖像和表格等類型。一個(gè)文檔對(duì)應(yīng)于用戶當(dāng)前打開的一個(gè)文件。文檔的主要作用是把數(shù)據(jù)處理從用戶界面的管理中分離出來(lái),集中處理數(shù)據(jù),同時(shí)提供與視圖交互的接口。7.2.1 數(shù)據(jù)成員n數(shù)據(jù)成員包括成員變量和成員函數(shù)。cdocument類為用戶定義的文

17、檔類提供了基本的函數(shù)功能。ncdocument支持標(biāo)準(zhǔn)操作,如創(chuàng)建、裝載、保存等??蚣苡胏document定義的界面來(lái)操作文檔。cdocument類的主要成員變量如下:ncstring m_strtitle:用于標(biāo)記文檔的標(biāo)題。ncstring m_strpathname:用于標(biāo)記文檔的路徑。ncdoctemplate *m_pdoctemplate:指向文檔模板的指針。ncptrlist m_viewlist:視圖列表。nbool m_bmodified:指明打開文檔后是否進(jìn)行了修改。nbool m_bautodelete:在沒有可用視圖時(shí)是否刪除自動(dòng)文檔。nbool m_bembedded

18、:是否可通過ole創(chuàng)建文檔。7.2.2 成員函數(shù)n1.addview函數(shù)n函數(shù)原型如下:nvoid addview(cview *pview);n說明:為當(dāng)前的文檔添加一個(gè)視圖。其中,參數(shù)pview 是指向新添加的視圖的指針。n2.cancloseframe函數(shù)n函數(shù)原型如下:nvirtual bool cancloseframe(cframewnd *pframe);n說明:應(yīng)用程序調(diào)用該函數(shù)判斷是否可以關(guān)閉pframe指向的窗口。如果能關(guān)閉,則返回非零值,否則,返回false。在默認(rèn)情況下,該函數(shù)先測(cè)試這個(gè)窗口是否是文檔的唯一窗口。如果是,則提示用戶存盤。n3.deletecontents

19、函數(shù)n函數(shù)原型如下: virtual void deletecontents();n說明:框架窗口調(diào)用該函數(shù)在不刪除cdocument對(duì)象的前提下刪除文檔中的數(shù)據(jù)。當(dāng)文檔被重復(fù)使用時(shí),調(diào)用該函數(shù)確保文檔為空。n4.getdoctemplate函數(shù)n函數(shù)原型如下:n cdoctemplate *getdoctemplate() const;n說明:調(diào)用該項(xiàng)函數(shù)得到一個(gè)指向當(dāng)前文檔使用的文檔模板的指針。當(dāng)文檔不是由文檔模板來(lái)管理時(shí),返回null。n5.getfile函數(shù)n函數(shù)原型如下:nvirtual cfile*getfile(lpctstr lpszfilename,uint nopenfla

20、gs,cfileexception*perror);n說明:得到一個(gè)cfile對(duì)象的指針。其中,lpszfilename 為指定文件的路徑的字符串,nopenflags為打開文件時(shí)指定文件的共享和存取方式,perror為指向錯(cuò)誤代碼的指針。n6.getfirstviewposition函數(shù)n函數(shù)原型如下:nvirtual position getfirstviewposition() const;n說明:利用該函數(shù)可得到與文檔相關(guān)的第一個(gè)視圖的位置,返回值可以供getnextview()函數(shù)使用。n7.getnextview函數(shù)n函數(shù)原型如下:nvirtual cview *getnextvi

21、ew(position &rposition) const;n說明:得到下一個(gè)視圖的位置。若當(dāng)前視圖是視圖系列中最后一幅時(shí),返回null。其中,參數(shù)rposition是前一幅視圖的位置。n8.getpathname函數(shù)n函數(shù)原型如下:nconst cstring &getpathname() const;n說明:返回當(dāng)前文檔存盤文件的完整路徑。n9.gettitle函數(shù)n函數(shù)原型如下:nconst cstring &gettitle() const;n說明:返回文檔的標(biāo)題,通常與文檔的文件名有關(guān)。n與其相對(duì)的是settitle()函數(shù),它用于設(shè)置文檔的標(biāo)題。其原型如下:

22、nvirtual void settitle(lpctstr lpsztitle);n10.ismodified函數(shù)n函數(shù)原型如下:nbool ismodified();n說明:檢測(cè)文檔是否被修改過。如果文檔被修改過,返回true。n11.onchangedviewlist函數(shù)n函數(shù)原型如下:nvirtual void onchangedviewlist();n說明:在文檔的視圖增加或減少時(shí)調(diào)用。默認(rèn)是當(dāng)文檔的最后一個(gè)視圖被刪除時(shí)自動(dòng)刪除文檔。n12.onclosedocument函數(shù)n函數(shù)原型如下:nvirtual void onclosedocument();n說明:關(guān)閉文檔時(shí)被調(diào)用。默認(rèn)

23、先調(diào)用deletecontents()函數(shù)刪除文檔數(shù)據(jù),然后再關(guān)閉視圖窗口。n13.onnewdocument函數(shù)n函數(shù)原型如下:nbool onnewdocument();n說明:在sdi應(yīng)用程序中,當(dāng)用戶在“文件”菜單中單擊“新建”菜單項(xiàng)時(shí),自動(dòng)調(diào)用框架窗口。onnewdocument()消除舊文檔內(nèi)容,得到一個(gè)“空”的文檔。而在mdi應(yīng)用程序中,框架自動(dòng)生成一個(gè)新的文檔對(duì)象,如果要調(diào)用onnewdocument()實(shí)現(xiàn)初始化,用戶可以在此處插入一個(gè)新文檔的初始化代碼。n14.onopendocument函數(shù)n函數(shù)原型如下:nvirtual bool onopendocument(lpct

24、str lpszpathname);n說明:在打開文檔的時(shí)候調(diào)用。其中,lpszpathname 為被打開文檔的路徑。n15.onsaveopendocument函數(shù)n函數(shù)原型如下:nvirtual bool onsavedocument(lpctstr lpszpathname);n說明:當(dāng)執(zhí)行“保存”和“另存為”命令時(shí)被調(diào)用。默認(rèn)時(shí),調(diào)用cobject:serialize函數(shù)將文檔數(shù)據(jù)存入文件。如果操作成功,返回true。n16.savemodified函數(shù)n函數(shù)原型如下:nvirtual bool savemodified();n說明:當(dāng)關(guān)閉一個(gè)被修改的文檔時(shí),調(diào)用該函數(shù)詢問是否需要保存

25、修改的文檔。如果成功地關(guān)閉了文檔,則返回true。n17.setmodifiedflag函數(shù)n函數(shù)原型如下:nvoid setmodifiedflag(bool bmodified=true);n說明:設(shè)置文檔的編輯標(biāo)志。當(dāng)用戶保存文檔后,文檔的bmodified自動(dòng)被設(shè)置為false。如果用戶退出程序時(shí),bmodified的標(biāo)志為true,系統(tǒng)會(huì)自動(dòng)提示用戶是否保存文檔。當(dāng)用戶在程序中某處修改了文檔數(shù)據(jù),在其后加上代碼pdoc-setmodifiedflag(true)可以有效地保證數(shù)據(jù)的安全。n18.serialize函數(shù)n函數(shù)原型如下:nvoid serialize(carchive &

26、amp;ar);n說明:當(dāng)用戶要把文檔中的內(nèi)容寫入文件或從文件中調(diào)出來(lái)時(shí),框架自動(dòng)調(diào)用文檔的serialize成員函數(shù)來(lái)實(shí)現(xiàn)文檔和文件的序列化。要注意的是,讀出數(shù)據(jù)的順序應(yīng)該和寫入數(shù)據(jù)的順序保持一致。n19.updateallviews函數(shù)n函數(shù)原型如下:nvoid updateallviews(cview *psender,lparam lhint=0l,cobject *phint=null);n說明:保證數(shù)據(jù)在文檔類及其視圖類中是一致的。視圖類接受用戶的輸入,則會(huì)將界面數(shù)據(jù)存儲(chǔ)到文檔數(shù)據(jù)中,而文檔類中的數(shù)據(jù)發(fā)生了變化,也應(yīng)該及時(shí)更新視圖類數(shù)據(jù),并刷新界面。7.2.3 文檔序列化n文檔類中

27、存儲(chǔ)數(shù)據(jù)的方法有多種,例如,使用對(duì)象指針、動(dòng)態(tài)對(duì)象數(shù)組、動(dòng)態(tài)鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)或哈希表來(lái)實(shí)現(xiàn)用戶自定義數(shù)據(jù)的存儲(chǔ)。文檔類通過“序列化機(jī)制”來(lái)管理文檔中數(shù)據(jù)的存取,序列化機(jī)制示意圖如圖7-8所示。如圖7-8 序列化機(jī)制n持久性(persistence)是指對(duì)象所具有的保存和加載其狀態(tài)的能力,即對(duì)象能夠在程序運(yùn)行結(jié)束前將對(duì)象的當(dāng)前狀態(tài)寫入永久性存儲(chǔ)體中,以后在程序再運(yùn)行時(shí)通過數(shù)據(jù)的讀取而恢復(fù)對(duì)象的狀態(tài)。這種對(duì)象的保存和恢復(fù)的過程稱為序列化(serialize)。n為了深入理解序列化操作,有必要了解對(duì)文檔不同操作后的具體程序運(yùn)行過程。n1.創(chuàng)建空文檔n應(yīng)用程序類的initinstance()函數(shù)在調(diào)用了a

28、dddoctemplate()函數(shù)之后,會(huì)通過cwinapp:processshellcommand間接調(diào)用cwinapp的成員函數(shù)onfilenew,并依次完成下列工作:n(1)構(gòu)造文檔對(duì)象,從磁盤中讀取數(shù)據(jù)。n(2)構(gòu)造主框架類cmainframe類的對(duì)象,并創(chuàng)建該主框架窗口,但不顯示。n(3)構(gòu)造視圖對(duì)象,并創(chuàng)建視圖窗口,同樣也不顯示。n(4)通過mfc內(nèi)部機(jī)制,建立主框架窗口、文檔和視圖對(duì)象之間的聯(lián)系。n(5)調(diào)用cdocument:onnewdocument()虛函數(shù),并調(diào)用cdocument:deletecontents()虛函數(shù)來(lái)清除文檔對(duì)象的內(nèi)容。n(6)調(diào)用cview:oni

29、nitialupdate()虛函數(shù)初始化視圖類的數(shù)據(jù)成員。n(7)調(diào)用cframewnd:activeframe()虛函數(shù),顯示帶有菜單、工具欄、狀態(tài)欄以及視圖窗口的主框架窗口。n2.打開文檔n在利用mfc應(yīng)用程序向?qū)?chuàng)建應(yīng)用程序時(shí),mfc會(huì)自動(dòng)將“文件”菜單中的“打開”命令映射到cwinapp類的onfileopen()成員函數(shù)。onfileopen()函數(shù)會(huì)完成下列操作:n(1)彈出通用文件“打開”對(duì)話框,供用戶選擇一個(gè)文檔。n(2)文檔指定后,調(diào)用文檔對(duì)象的cdoucment:onopendocument()虛函數(shù)。這個(gè)函數(shù)將打開文檔,并調(diào)用deletecontents()函數(shù)清除文檔對(duì)

30、象的內(nèi)容,然后創(chuàng)建一個(gè)carchive對(duì)象用于數(shù)據(jù)的讀取,接著又自動(dòng)調(diào)用serialize()函數(shù)。n(3)調(diào)用視圖對(duì)象的cview:oninitialupdate()虛函數(shù)初始化視圖類的數(shù)據(jù)成員。n3.保存文檔n在利用mfc應(yīng)用程序向?qū)?chuàng)建應(yīng)用程序時(shí),它會(huì)自動(dòng)將“文件”菜單中的“保存”命令與文檔類的onfilesave成員函數(shù)在內(nèi)部關(guān)聯(lián)。onfilesave()函數(shù)會(huì)完成下列操作:n(1)彈出通用文件“保存”對(duì)話框,讓用戶輸入一個(gè)文件名。n(2)調(diào)用文檔類對(duì)象的cdocument:onsavedocument()虛函數(shù),接著又自動(dòng)調(diào)用serialize()函數(shù),將carchive對(duì)象的內(nèi)容保

31、存在文檔中。n4.關(guān)閉文檔n當(dāng)用戶試圖關(guān)閉文檔(或退出應(yīng)用程序)時(shí),應(yīng)用程序會(huì)根據(jù)用戶對(duì)文檔的修改與否來(lái)進(jìn)一步完成下列任務(wù)。n(1)若文檔內(nèi)容已修改,則彈出一個(gè)“消息”對(duì)話框,詢問用戶是否保存修改后的文檔。當(dāng)用戶選擇“是”,則應(yīng)用程序執(zhí)行onfilesave過程。n(2)調(diào)用cdocument:onclosedocument()虛函數(shù),關(guān)閉所有與該文檔相關(guān)聯(lián)的文檔窗口及相應(yīng)的視圖,調(diào)用文檔類的deletecontents清除文檔數(shù)據(jù)。n用戶經(jīng)常需要自己定義類來(lái)實(shí)現(xiàn)序列化操作,以完成某些特定的功能,mfc為滿足用戶的這個(gè)需要規(guī)定了自定義類實(shí)現(xiàn)序列化必須滿足以下4個(gè)條件:n(1)類必須是直接或間接

32、地從cobject類派生。n(2)類必須定義一個(gè)不帶參數(shù)的構(gòu)造函數(shù)。當(dāng)從磁盤載入文檔時(shí)調(diào)用該構(gòu)造函數(shù)來(lái)創(chuàng)建一個(gè)可序列化的對(duì)象,使用從文件中讀出來(lái)的數(shù)據(jù)填充對(duì)象的成員變量。n(3)要使用mfc序列化宏。在類的頭文件中使用declare_serial宏,在類的實(shí)現(xiàn)文件中使用implement_serial宏。n(4)自定義類必須重載序列化成員函數(shù)serialize()。由于不同類的數(shù)據(jù)結(jié)構(gòu)各不相同,可序列化的類應(yīng)該重載serialize()函數(shù),使其支持對(duì)特定數(shù)據(jù)的序列化。并且,任何需要序列化的對(duì)象都應(yīng)該在文檔派生類中作為數(shù)據(jù)成員進(jìn)行聲明。7.3 視圖n視圖(view)是文檔在應(yīng)用程序窗口中的一個(gè)

33、映像。視圖就像一個(gè)觀景器,用戶通過視圖查看和修改文檔,視圖充當(dāng)了文檔與用戶之間的媒介物。應(yīng)用程序通過視圖向用戶顯示文檔中的數(shù)據(jù),并把用戶的輸入解釋為對(duì)文檔的操作。一個(gè)視圖總是與一個(gè)文檔對(duì)象相關(guān)聯(lián),用戶通過與文檔相關(guān)聯(lián)的視圖與文檔進(jìn)行交互。當(dāng)用戶打開一個(gè)文檔時(shí),應(yīng)用程序就會(huì)創(chuàng)建一個(gè)與之相關(guān)聯(lián)的視圖。7.3.1 視圖的特點(diǎn)n視圖主要有以下幾方面特點(diǎn):n(1)多個(gè)視圖可以共享一個(gè)主窗口。n(2)cdoctemplate為視圖、主窗口和文檔之間建立相互聯(lián)系。n(3)當(dāng)用戶打開或切分窗口時(shí),應(yīng)用程序?qū)?gòu)造一個(gè)視圖,并將它連接到相應(yīng)的文檔。n(4)一個(gè)視圖只能擁有一個(gè)文檔,而一個(gè)文檔可以擁有多個(gè)視圖。n(

34、5)視圖接收由程序框架傳給它的命令,如果視圖不能處理該命令,就將其傳遞給相關(guān)聯(lián)的文檔處理。n(6)視圖可處理多種類型的輸入和命令,如鍵盤輸入、鼠標(biāo)輸入、菜單命令、工具欄命令等。n(7)視圖負(fù)責(zé)顯示和修改文檔數(shù)據(jù)。在應(yīng)用程序中可以使用視圖直接讀取文檔的數(shù)據(jù),也可以在文檔中提供由視圖調(diào)用的函數(shù)來(lái)獲取文檔數(shù)據(jù)。7.3.2 視圖的成員函數(shù)n1.ondraw函數(shù)n函數(shù)原型如下:nvoid ondraw(cdc*pdc);n其中,pdc為指向打印設(shè)備描述表的指針。n說明:當(dāng)用戶執(zhí)行屏幕顯示、打印和打印預(yù)覽時(shí),框架將調(diào)用該函數(shù)在輸出設(shè)備上顯示文檔數(shù)據(jù),因此ondraw函數(shù)是編程時(shí)需要覆蓋的函數(shù)之一。n2.g

35、etdocument函數(shù)n函數(shù)原型如下:ncdocument *getdocument() const;n(cdocument 派生類) *getdocument() const;n說明:獲得與視圖類相關(guān)連的文檔對(duì)象指針。在視圖類中可用getdocument獲取與之關(guān)聯(lián)的文檔對(duì)象的指針,取得對(duì)文檔數(shù)據(jù)、對(duì)象、對(duì)象集合的訪問。通過該函數(shù)還可以獲得指向視圖對(duì)象所屬的文檔的文檔指針m_pdocument。n3.onupdate 函數(shù)n函數(shù)原型如下:nvirtual void onupdate(cview *psender,lparam lhint, cobject *phint);n其中,參數(shù)“ps

36、ender”表示與被更改的文檔類相關(guān)聯(lián)的視圖類的指針,當(dāng)為null時(shí),表示所有的視圖都需要更新。n說明:onupdate函數(shù)是一個(gè)虛函數(shù),它負(fù)責(zé)更新數(shù)據(jù),對(duì)文檔數(shù)據(jù)的正確顯示起必要的支持作用。n4.oninitialupdate函數(shù)n函數(shù)原型如下:nvoid oninitialupdate();n說明:oninitialupdate函數(shù)用于初始化視圖類的數(shù)據(jù)成員。n5.isselected函數(shù)n函數(shù)原型如下:nvirtual bool isselected(const cobject*pdocitem)const;n說明:判斷指定的文檔項(xiàng)目是否被選中,如果沒有選中,則返回零值,否則返回非零值。

37、n該函數(shù)由框架調(diào)用,檢查指定的文檔項(xiàng)目是否被選中。pdocitem為指向要測(cè)試的文檔項(xiàng)目的指針。n6.onscroll 函數(shù)n函數(shù)原型如下:nvirtual bool cview:onscroll(uint nscrollcode,uint npos,bool bdoscroll=true);n說明:框架調(diào)用這個(gè)函數(shù)以確定視圖是否能夠滾動(dòng)。如果bdoscroll為true,并且視圖確實(shí)被滾動(dòng)了,則返回非零值;否則返回零。如果bdoscroll為false,則返回當(dāng)bdoscroll為true時(shí)應(yīng)當(dāng)返回的值,即使沒有做實(shí)際的滾動(dòng)。n7.onpreparedc 函數(shù)n函數(shù)原型如下:nvirtual

38、 void onpreparedc(cdc *pdc, cprintinfo *pinfo=null);n說明:在調(diào)用ondraw()函數(shù)前允許由mfc調(diào)用該函數(shù)修改設(shè)備描述表。其中,參數(shù)pdc為指向設(shè)備環(huán)境的指針,用于畫出文檔的圖像。pinfo 為指向cprintinfo結(jié)構(gòu)的指針,如果onpreparedc是為打印或打印預(yù)覽調(diào)用的,則該結(jié)構(gòu)描述了當(dāng)前打印任務(wù),m_ncurpage成員指定了要打印的頁(yè)數(shù)。如果onpreparedc是為屏幕顯示而調(diào)用的,則這個(gè)參數(shù)為null。n在下列情況下,應(yīng)該重載onpreparedc:n(1)要為指定的頁(yè)面調(diào)整設(shè)備環(huán)境的屬性。例如,如果想要設(shè)置設(shè)備環(huán)境的映

39、射模式或者其他特征,則應(yīng)在這個(gè)函數(shù)中完成這些操作。n(2)要實(shí)現(xiàn)打印時(shí)的分頁(yè)。通常應(yīng)當(dāng)在打印開始時(shí)利用onprepareprinting成員函數(shù)來(lái)指定文檔的長(zhǎng)度。但是,如果并不知道文檔的確切長(zhǎng)度(例如,當(dāng)打印數(shù)據(jù)庫(kù)中未知數(shù)量的記錄時(shí)),則應(yīng)重載onpreparedc函數(shù),以便在打印時(shí)檢測(cè)是否到了文檔的末尾。如果已經(jīng)沒有文檔需要打印了,將cprintinfo結(jié)構(gòu)的m_bcontinueprinting成員設(shè)為false。n(3)要按頁(yè)發(fā)送打印機(jī)的轉(zhuǎn)義序列碼。要在onpreparedc中發(fā)送轉(zhuǎn)義序列碼,則應(yīng)調(diào)用pdc成員的escape成員函數(shù)。n除了該函數(shù),視圖類還提供了其他4個(gè)關(guān)于打印的函數(shù)。n

40、onbeginprinting函數(shù):重載該函數(shù)可以創(chuàng)建打印文檔所需要的資源。nonendprinting函數(shù):重載該函數(shù)可以釋放在onbeginprinting函數(shù)中創(chuàng)建的資源。nonprepareprinting函數(shù):重載該函數(shù)可以提供文檔的最大打印頁(yè)數(shù)。nonprint函數(shù):重載該函數(shù)可以提供如打印頁(yè)眉頁(yè)腳等的附加打印服務(wù)。7.3.3 視圖的操作方法ncview 類及其派生視圖類是用戶的數(shù)據(jù)窗口,它控制著應(yīng)用程序文檔內(nèi)容的顯示以及用戶和應(yīng)用程序文檔的交互。同時(shí),cview類的派生類分別支持各種不同的功能,可以根據(jù)需要選擇適當(dāng)?shù)呐缮?。n對(duì)視圖操作的一般步驟如下:n(1)獲得與其相關(guān)聯(lián)的文檔

41、對(duì)象指針。在視圖類中可用getdocument獲取與之關(guān)聯(lián)的文檔對(duì)象的指針,取得對(duì)文檔數(shù)據(jù)、對(duì)象、對(duì)象集合的訪問。例如,cdocument*pdoc=getdocument()。n(2)在ondraw函數(shù)中添加要重新繪制的模塊。n在ondraw函數(shù)中對(duì)需要重新繪制的功能模塊再次操作,以避免在刷新視圖時(shí)所繪內(nèi)容丟失。例如,在該函數(shù)外繪制了一條直線pdc-lineto(50,100),如果沒有在這個(gè)函數(shù)內(nèi)重新調(diào)用繪制直線的操作,在視圖刷新后將看不到所繪直線。n(3)使用onupdate函數(shù)更新、同步數(shù)據(jù)。nonupdate函數(shù)負(fù)責(zé)更新數(shù)據(jù),提供對(duì)文檔正確顯示的支持。數(shù)據(jù)一旦發(fā)生變化,利用這個(gè)函數(shù)就

42、可以保持文檔和視圖中數(shù)據(jù)的一致性。n(4)通過界面與用戶交互。nwindows標(biāo)準(zhǔn)消息是直接發(fā)送到視圖對(duì)象的。在處理各種命令消息時(shí),視圖類的優(yōu)先級(jí)也比較高,而且視圖中顯示文檔數(shù)據(jù)。因此,使用視圖對(duì)象對(duì)用戶輸入進(jìn)行響應(yīng)是理所當(dāng)然的。n刷新視圖時(shí)默認(rèn)的函數(shù)調(diào)用過程是cdocument:updateallviews()-cview:onupdate()-cwnd:invalidate()-onpaint()-ondraw()。7.4 基礎(chǔ)實(shí)例 單文檔應(yīng)用程序n1.編程要求n編寫一個(gè)簡(jiǎn)易的存儲(chǔ)學(xué)生成績(jī)信息的程序,具體功能要求為:首先通過對(duì)話框來(lái)輸入一個(gè)學(xué)生記錄,包括學(xué)生的姓名、學(xué)號(hào)和3門課程的成績(jī)。然

43、后,將記錄內(nèi)容保存到一個(gè)對(duì)象數(shù)組集合類對(duì)象中,最后通過文檔序列化將記錄保存到一個(gè)文件中。當(dāng)添加記錄或打開一個(gè)記錄文件時(shí),還會(huì)將數(shù)據(jù)顯示在文檔窗口(視圖)中。n2.編程實(shí)現(xiàn)n1)添加用于輸入學(xué)生成績(jī)信息的對(duì)話框n2)添加一個(gè)cstudentscore類并使其可序列化n3)添加并處理菜單項(xiàng)n4)完善代碼n5)編譯運(yùn)行并測(cè)試,結(jié)果如圖7-10所示7.5 提高實(shí)例 多文檔應(yīng)用程序n1.編程要求n編寫一個(gè)一檔多視的程序,在各自mdi文檔窗口中包含同一個(gè)視圖類的多個(gè)視圖對(duì)象。這個(gè)實(shí)例可以為同一個(gè)文檔數(shù)據(jù)提供兩種不同的顯示和編輯方式,其效果如圖7-11所示。n在左邊的窗格中,用戶可以輸入起點(diǎn)坐標(biāo)和終點(diǎn)坐標(biāo),

44、相應(yīng)的右邊窗格中就會(huì)顯示出以輸入的起點(diǎn)和終點(diǎn)為坐標(biāo)的一條直線;也可以在右邊窗格中通過按鼠標(biāo)左鍵拖動(dòng)的方法改變左邊窗格中的起點(diǎn)坐標(biāo)和終點(diǎn)坐標(biāo),并在右邊窗格中顯示出相應(yīng)的直線。n2.編程實(shí)現(xiàn)n(1)利用mfc appwizard創(chuàng)建一個(gè)多文檔應(yīng)用程序drawlinemdiapp。在“mfc應(yīng)用程序向?qū)?步驟6共6步”對(duì)話框中為cdrawlinemdiappview類選擇基類“cformview”,如圖7-12所示,其他步驟使用默認(rèn)值即可。n(2)按圖7-12的布局添加所需控件,并對(duì)其進(jìn)行相應(yīng)的設(shè)置。該應(yīng)用程序所需控件有3個(gè)組框,4個(gè)靜態(tài)控件和4個(gè)編輯框。在工作區(qū)的resourceview頁(yè)面中雙擊

45、dialog下的“idd_drawlinemdiapp_form”,添加控件。n最后,為編輯框控件添加成員變量。n(3)添加cdrawlinemdiappdoc和cdrawlinemdiappview類代碼。n首先,在cdrawlinemdiappdoc類中添加兩個(gè)公有型的cpoint數(shù)據(jù)成員m_startpoint和m_endpoint,分別表示直線的開始坐標(biāo)和終止坐標(biāo)。n然后在cdrawlinemdiappdoc類的構(gòu)造函數(shù)內(nèi)添加下列代碼以初始化坐標(biāo)。ncdrawlinemdiappdoc:cdrawlinemdiappdoc()nn m_startpoint.x=m_startpoint.y=0;n m_endpoint.x=m_endpoint.y=0;nn切換到mfc classwizard的message maps標(biāo)簽頁(yè),在cdrawlinemdiappview類中為4個(gè)編輯框添加en_change消息映射,將它們的映射函數(shù)名都設(shè)為onchangeedit,并添加如下代碼以接收編輯框控件的值。nvoid cdrawlinemdiappview:onchangeedit() nn/從編輯框中獲取數(shù)據(jù)nupdatedata();ncdrawlinemdiappdoc*pdoc=(cdrawlinemdiappdoc*)getdocument

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論