文檔視圖上機(jī)指導(dǎo)書_第1頁(yè)
已閱讀1頁(yè),還剩26頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、<p><b>  文檔視圖上機(jī)指導(dǎo)書</b></p><p>  【例8.1】文檔視圖結(jié)構(gòu)應(yīng)用程序例子(Ex_DocView)。</p><p> ?。?)創(chuàng)建基于CFormView類的多文檔應(yīng)用程序</p><p>  用MFC AppWizard(exe)創(chuàng)建一個(gè)默認(rèn)的多文檔應(yīng)用程序Ex_DocView,但在向?qū)У牡诹綄Ex

2、_DocViewView的基類由默認(rèn)的CView選擇為CFormView類,如圖8.2所示。</p><p>  圖8.2 設(shè)置視圖的基類為CFormView類</p><p> ?。?)添加應(yīng)用程序所需的數(shù)據(jù)</p><p>  第一步 在Visual C++中,選擇菜單【插入】【新建類】,打開(kāi)新建類對(duì)話框。在“Class type”組合框中選擇Generic

3、Class,類名為CStudent,默認(rèn)的類文件為Student.cpp,設(shè)置該類的父類為CObject,并單擊【OK】按鈕。如圖8.3所示。</p><p>  圖8.3 添加CStudent類</p><p>  第二步 打開(kāi)項(xiàng)目工作區(qū)的文件視圖,雙擊打開(kāi)Student.h文件,如圖8.4所示,編輯CStudent類定義的代碼如下:</p><p>  cla

4、ss CStudent : public CObject </p><p><b>  {</b></p><p><b>  public:</b></p><p>  long m_nCode;</p><p>  CString m_sName;</p><p>  

5、long m_lAge;</p><p>  double m_lScore;</p><p>  CStudent();</p><p>  CStudent(long,CString,long ,double);</p><p>  virtual ~CStudent();</p><p><b>  }

6、;</b></p><p>  圖8.4 打開(kāi)Student.h文件</p><p>  第三步 同上步,編輯Student.cpp文件,修改類CStudent的構(gòu)造函數(shù)實(shí)現(xiàn)代碼如下:</p><p>  CStudent::CStudent(long code,CString name,long age,double score)</p>

7、<p><b>  {</b></p><p>  m_nCode=code;</p><p>  m_sName=name; </p><p>  m_lAge=age;</p><p>  m_lScore=score;</p><p><b>  }</b>

8、;</p><p>  第四步 在Ex_DocViewDoc.h文件中,為類CEx_DocViewDoc添加數(shù)據(jù)成員:</p><p>  class CEx_DocViewDoc : public CDocument</p><p><b>  {</b></p><p><b>  ……</b>

9、</p><p><b>  public:</b></p><p>  POSITION curPos;</p><p>  CTypedPtrList <CObList, CStudent*> m_dataList; </p><p><b>  ……</b></p>

10、<p><b>  }</b></p><p>  說(shuō)明:m_dataList定義為CStudent類指針的表CtypedPtrList變量,curPos定義為POSITION變量,用來(lái)指示當(dāng)前指針。</p><p>  第五步 在文件stdafx..h中加入添加如下代碼:</p><p>  #include<afxtem

11、pl.h></p><p>  因?yàn)樵诔绦蛑惺褂昧四0孱怌TypedPtrList<CObList, CStudent*>。</p><p>  第六步 在Ex_DocViewDoc.h文件的頭部添加如下代碼:</p><p>  #include "Student.h"</p><p>  第七步 在文

12、檔關(guān)閉時(shí),需要清除m_dataList占用的內(nèi)存,利用屬性窗口為CEx_DocViewDoc類加入虛函數(shù)DeleteContens(),并添加代碼:</p><p>  void CEx_DocViewDoc::DeleteContents() </p><p><b>  {</b></p><p>  while(!m_dataList.I

13、sEmpty()) delete m_dataList.RemoveHead();</p><p>  CDocument::DeleteContents();</p><p><b>  }</b></p><p> ?。?)修改IDD_EX_DOCVIEW_FORM對(duì)話框資源,添加應(yīng)用程序所需控件:</p><

14、p>  ■ 第一步 打開(kāi)項(xiàng)目工作區(qū)的資源視圖,雙擊打開(kāi)IDD_EX_DOCVIEW_FORM對(duì)話框資源如圖8.5所示,編輯IDD_EX_DOCVIEW_FORM對(duì)話框資源,如圖8.6所示。</p><p>  圖8.5 打開(kāi)對(duì)話框資源 圖8.6 編輯后的對(duì)話框控件</p><p>  ■ 第二步 設(shè)置圖8.6各控件的屬性如表8.1所示。</p>&

15、lt;p>  表8.1 添加的控件</p><p>  ■ 第三步 打開(kāi)MFC ClassWizard的Member Variable頁(yè)面,確定Class Name是CEx_DocViewView,如圖8.7所示。選中所需的控件ID號(hào),雙擊鼠標(biāo)。依次為下列控件添加成員變量,如下表8.2所示。</p><p>  圖8.7 為CEx_DocViewView添加成員變量</p&

16、gt;<p>  表8.2 控件變量</p><p> ?。?)為按鈕編寫消息響應(yīng)函數(shù)</p><p>  ■ 第一步 用MFC ClassWizard為按鈕IDC_ADD添加BN_CLICKED的消息映射,如圖8.8所示,單擊【添加函數(shù)】按鈕為CEx_DocViewView添加OnAdd( )成員函數(shù),再單擊【編輯代碼】按鈕為該含函數(shù)加入下列代碼:</p>

17、<p>  void CEx_DocViewView::OnAdd() </p><p><b>  {</b></p><p>  UpdateData(); </p><p>  CEx_DocViewDoc *pDoc=GetDocument();</p><p>  ASSERT_VALID(pDoc)

18、; </p><p>  CStudent *pStudent;</p><p>  pStudent=new CStudent(m_nCode,m_sName,m_lAge,m_lScore);</p><p>  pDoc->m_dataList.AddTail(pStudent); </p><p>  pDoc->curP

19、os=pDoc->m_dataList.GetHeadPosition();</p><p><b>  }</b></p><p>  圖8.8 為按鈕IDC_ADD編寫消息響應(yīng)函數(shù)</p><p>  說(shuō)明:UpdateData()函數(shù)迫使對(duì)話框編輯控件和相應(yīng)變量之間傳送數(shù)據(jù),該函數(shù)原型為:BOOL UpdateData(BOOL

20、bSaveAndValidate::TRUE);其中bSaveAndValidate為true時(shí)表示數(shù)據(jù)已經(jīng)更新。</p><p>  在CEx_DocViewView::OnAdd()函數(shù)中,取得指向文檔的指針,操作文檔對(duì)象的成員變量m_dataList,首先使用用戶輸入的變量值構(gòu)造一個(gè)新CStudent對(duì)象,然后將其加入m_dataList表尾,最后將curPos指向表頭。通過(guò)上面的操作,一個(gè)新CStuden

21、t對(duì)象就加到m_dataList表中。</p><p>  ■ 第二步 同上步,用MFC ClassWizard為按鈕IDC_NEXT添加BN_CLICKED的消息映射,并增加下列代碼:</p><p>  void CEx_DocViewView::OnNext() </p><p><b>  {</b></p><p&

22、gt;  CEx_DocViewDoc *pDoc =GetDocument();</p><p>  ASSERT_VALID(pDoc);</p><p>  if(pDoc->curPos!=NULL) </p><p><b>  {</b></p><p>  CStudent *pStudent=(

23、CStudent *)pDoc->m_dataList.GetAt(pDoc->curPos);</p><p>  m_nCode=pStudent->m_nCode;</p><p>  m_sName=pStudent->m_sName;</p><p>  m_lAge=pStudent->m_lAge;</p>

24、<p>  m_lScore=pStudent->m_lScore;</p><p>  UpdateData(false); </p><p>  pDoc->m_dataList.GetNext(pDoc->curPos);</p><p>  if(pDoc->curPos==NULL)</p><p

25、>  pDoc->curPos=pDoc->m_dataList.GetHeadPosition();</p><p><b>  }</b></p><p><b>  else</b></p><p>  MessageBox("當(dāng)前列表中沒(méi)有數(shù)據(jù)!");</p>&

26、lt;p><b>  }</b></p><p>  說(shuō)明:CEx_DocViewView::OnNext函數(shù)用來(lái)循環(huán)遍歷m_dataList表,首先得到文檔指針,然后判斷,如果curPos為空,就說(shuō)明沒(méi)有數(shù)據(jù),因?yàn)樵贠nAdd函數(shù)中將其設(shè)在表頭。如果表不空,就進(jìn)行循環(huán)遍歷。</p><p>  ■ 第三步 編譯運(yùn)行并測(cè)試,結(jié)果見(jiàn)圖8.1</p>

27、<p>  【例8.2】文檔視圖結(jié)構(gòu)應(yīng)用程序例子(Editor)。</p><p>  (1)創(chuàng)建單文檔應(yīng)用程序Editor</p><p>  ■ 第一步 用MFC AppWizard(exe)創(chuàng)建一個(gè)默認(rèn)的單文檔應(yīng)用程序Editor,但在向?qū)У牡谒牟絾螕簟続dvanced】按鈕,彈出AdvancedOption對(duì)話框,設(shè)置文檔視圖結(jié)構(gòu)的一些屬性,如圖8.9所示。</p&

28、gt;<p>  圖8.9 Advanced Option對(duì)話框</p><p>  該對(duì)話框提供的Document Template String(文檔模板字符串)標(biāo)簽頁(yè),該項(xiàng)的值將與應(yīng)用程序類中定義文檔模板類對(duì)象的第一個(gè)文檔模板字符串IDR_MAINFRAME對(duì)應(yīng)。它包括以下幾個(gè)文本框:</p><p>  File extension:指定應(yīng)用程序創(chuàng)建的文檔所用的文件

29、名后綴。輸入后綴名.txt,表明Editor使用文本文件的后綴名.TXT;</p><p>  File type ID:用于在Windows的注冊(cè)數(shù)據(jù)庫(kù)中標(biāo)識(shí)應(yīng)用程序的文檔類型;</p><p>  Main frame caption:主框架窗口標(biāo)題,默認(rèn)情況下與項(xiàng)目名相一致;</p><p>  Doc type name:文檔類型名,指定與一個(gè)從CDocu

30、ment派生的文檔類相關(guān)的文檔類型名;</p><p>  Filter name:用作“打開(kāi)文件”、“保存文件”對(duì)話框中的過(guò)濾器。Visual Studio會(huì)自動(dòng)根據(jù)輸入的后綴名生成一個(gè)過(guò)濾器:Editor Files(*.txt)。這樣,當(dāng)在Open File對(duì)話框中選擇Editor Files(*.txt)時(shí),只有以.txt為后綴名的文件名顯示在文件名列表中;</p><p>  F

31、ile new name(short name):用于指定在new對(duì)話框中使用的文檔名。當(dāng)應(yīng)用程序支持多種文檔類型時(shí),選擇【Fi1e】【New】命令會(huì)彈出一個(gè)對(duì)話框,列出應(yīng)用程序所支持的所有文檔類型,供用戶選擇。選擇一種文檔類型后,自動(dòng)創(chuàng)建相應(yīng)類型的文檔。</p><p>  File type name(long name):用于指定當(dāng)應(yīng)用程序作為OLE Automation服務(wù)器時(shí)使用的文檔類型名,使用默認(rèn)值

32、。</p><p> ?。?)添加應(yīng)用程序所需的數(shù)據(jù)</p><p>  ■ 第一步 打開(kāi)項(xiàng)目工作區(qū)的文件視圖,雙擊打開(kāi)EditorDoc.h文件,如圖8.10所示,并在該文件中,定義文檔的數(shù)據(jù)成員,加入以下代碼:</p><p>  class CEditorDoc : public CDocument</p><p><b> 

33、 {</b></p><p><b>  ……</b></p><p><b>  public:</b></p><p>  CStringList lines; // 鏈表CStringList來(lái)保存文本編輯器的數(shù)據(jù)</p><p>  int nLineNum; // 用于

34、指示當(dāng)前編輯行行號(hào)</p><p><b>  ……</b></p><p><b>  }</b></p><p>  圖8.10 打開(kāi)EditorDoc.h文件</p><p>  ■ 第二步 同上步,打開(kāi)在EditorDoc.cpp文件,在CEditorDoc::OnNewDocument(

35、)成員函數(shù)加入初始化數(shù)據(jù)成員的代碼:</p><p>  BOOL EditorDoc::OnNewDocument()</p><p><b>  {</b></p><p>  if (!CDocument::OnNewDocument()) return FALSE;</p><p>  nLineNum=

36、0;</p><p>  POSITION pos; // pos指向鏈表當(dāng)前元素。</p><p>  pos=lines.GetHeadPosition(); // 返回鏈表頭指針</p><p>  while(pos!=NULL)</p><p>  ((CString)lines.GetNext(pos)).E

37、mpty();</p><p>  lines.RemoveAll(); // 清除鏈表中的所有指針</p><p>  return TRUE;</p><p><b>  }</b></p><p>  說(shuō)明:語(yǔ)句((CString)lines.GetNext(pos)).Empty()的作用是:

38、以當(dāng)前pos為參數(shù),返回下一個(gè)元素指針,同時(shí)修改pos,使它指向下一個(gè)元素。使用強(qiáng)制類型轉(zhuǎn)換將GetNext()函數(shù)返回的元素指針轉(zhuǎn)化為CString類型,然后調(diào)用Cstring::Empty()方法清除該行中的所有字符。通過(guò)一個(gè)while循環(huán),清除所有文本行的數(shù)據(jù)。</p><p>  一般地,類的數(shù)據(jù)成員的初始化都是在構(gòu)造函數(shù)中完成的,但由于文檔對(duì)象創(chuàng)建后,需要反復(fù)刷新而不是反復(fù)創(chuàng)建,因此文檔類的數(shù)據(jù)成員初始

39、化工作放在OnNewDocument成員函數(shù)中完成而不在構(gòu)造函數(shù)中做這件事情。</p><p>  ■ 第三步 用MFC ClassWizard為CEditorDoc類添加虛函數(shù)DeleteContents(),如圖8.11所示。同時(shí),增加下述代碼:</p><p>  void CEditorDoc::DeleteContents() </p><p><b

40、>  {</b></p><p>  nLineNum=0;</p><p>  POSITION pos;</p><p>  pos=lines.GetHeadPosition();</p><p>  while(pos!=NULL)</p><p>  ((CString)lines.GetN

41、ext(pos)).Empty();</p><p>  lines.RemoveAll();</p><p>  CDocument::DeleteContents();</p><p><b>  }</b></p><p>  圖8.11 為CEditorDoc類添加虛函數(shù)</p><p>

42、;  說(shuō)明:在使用【File】【Open】命令打開(kāi)一個(gè)文檔或關(guān)閉應(yīng)用程序時(shí),都需要清理文檔對(duì)象中的數(shù)據(jù)。文檔的清理是在文檔的CDocument::DeleteContents()虛函數(shù)中完成的。DeleteContents()成員函數(shù)需要反復(fù)調(diào)用,它的功能是刪除文檔的數(shù)據(jù),并確信一個(gè)文檔在使用前為空。有讀者可能想到在析構(gòu)函數(shù)中清理文檔數(shù)據(jù),但析構(gòu)函數(shù)只在文檔對(duì)象結(jié)束時(shí)調(diào)用,用于清除那些在對(duì)象生存期都將存在的數(shù)據(jù)項(xiàng),顯然析構(gòu)函數(shù)不能滿足重

43、復(fù)調(diào)用的要求。</p><p><b>  (3)處理鍵盤輸入</b></p><p>  ■ 第一步 在文檔類的頭文件EditorDoc.h中,定義視圖類的數(shù)據(jù)成員,加入以下代碼:</p><p>  class CEditorView : public CView</p><p><b>  {</b

44、></p><p><b>  ……</b></p><p>  int lHeight;int cWidth;</p><p><b>  ……</b></p><p><b>  }</b></p><p>  ■ 第二步 用MFC Clas

45、sWizard為CEditorView類添加虛函數(shù)OnInitialUpdate(),并增加下列代碼:</p><p>  void CEditorView::OnInitialUpdate() </p><p><b>  {</b></p><p>  CDC *pDC=GetDC(); // 取得當(dāng)前窗口的設(shè)備場(chǎng)境指針

46、并存放在pDC中</p><p>  TEXTMETRIC tm;</p><p>  pDC->GetTextMetrics(&tm);</p><p>  lHeight=tm.tmHeight+tm.tmExternalLeading;</p><p>  cWidth=tm.tmAveCharWidth;</p&g

47、t;<p>  CView::OnInitialUpdate();</p><p><b>  }</b></p><p>  說(shuō)明:視圖類一般在CView::OnInitialUpdate()成員函數(shù)來(lái)初始化視圖類的數(shù)據(jù)成員。因?yàn)檫@時(shí),視圖窗口已經(jīng)創(chuàng)建,馬上開(kāi)始更新,那么可能影響視圖顯示的數(shù)據(jù)一定要在這時(shí)初始化。</p><p>

48、;  在以下情況下,應(yīng)用程序?qū)⒆詣?dòng)執(zhí)行視圖類的OnInitialUpdate()來(lái)初始化視圖類數(shù)據(jù)成員:</p><p>  調(diào)用CDocument::OnNewDocument時(shí);</p><p>  調(diào)用CDocument::OnOpenDocument時(shí)需要清除視圖原有的顯示內(nèi)容。</p><p>  TEXTMETRIC是一個(gè)數(shù)據(jù)結(jié)構(gòu),它包含字體的寬度、高度

49、、字的前后空白等字段。調(diào)用CDC::GetTextMetrics()獲取字體的TEXTMETRIC,從而取得字體的寬度和高度等信息。</p><p>  ■ 第三步 用MFC ClassWizard為類CEditorView添加WM_CHAR的消息處理函數(shù)OnChar(),如圖8.12所示。打開(kāi)CEditorView::OnChar()函數(shù)進(jìn)行編輯。修改后的OnChar函數(shù)如下:</p><p

50、>  void CEditorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) </p><p><b>  {</b></p><p>  CEditorDoc* pDoc=GetDocument();</p><p>  CClientDC dc(this);</p>

51、<p>  CString line(""); // 存放編輯器當(dāng)前行字符串</p><p>  POSITION pos=NULL; // 字符串鏈表位置指示</p><p>  if(nChar=='\r')

52、// 若是回車,則增加一行</p><p><b>  {</b></p><p>  pDoc->nLineNum++;</p><p><b>  }</b></p><p><b>  else</b></p><p><b>  

53、{</b></p><p>  // 按行號(hào)返回字符串鏈表中位置值</p><p>  pos=pDoc->lines.FindIndex(pDoc->nLineNum);</p><p><b>  if(!pos)</b></p><p><b>  {</b></

54、p><p>  // 沒(méi)有找到該行號(hào)對(duì)應(yīng)的行,因此它是一個(gè)空行,把它加到字符串鏈表中</p><p>  line+=(char)nChar;</p><p>  pDoc->lines.AddTail(CString(line));</p><p><b>  }</b></p><p>&l

55、t;b>  else{</b></p><p>  // 當(dāng)前文本行還沒(méi)有換行結(jié)束,因此將文本加入到行末</p><p>  line=pDoc->lines.GetAt(pos);</p><p>  line+=(char)nChar;</p><p>  pDoc->lines.SetAt(pos,line

56、);</p><p><b>  }</b></p><p>  TEXTMETRIC tm;</p><p>  dc.GetTextMetrics(&tm);</p><p>  dc.TextOut(0,</p><p>  (int)pDoc->nLineNum*tm.tmH

57、eight,</p><p><b>  line,</b></p><p>  line.GetLength());</p><p><b>  }</b></p><p>  CView::OnChar(nChar, nRepCnt, nFlags);</p><p>&

58、lt;b>  }</b></p><p><b>  } </b></p><p>  圖8.12 為CEditorView類添加消息處理函數(shù)</p><p>  說(shuō)明:編輯器要不斷接收用戶的鍵盤輸入,就必須處理鍵盤消息。每按下一個(gè)字符,窗口就會(huì)接收到一個(gè)消息WM_CHAR。WM_CHAR消息是在視圖類中處理的,對(duì)該消息的處

59、理過(guò)程大致包括:讀取用戶輸入的字符,如果輸入是一個(gè)回車,則將總行數(shù)nLineNum加1,否則將輸入字符加到當(dāng)前行行末。最后調(diào)用TextOut函數(shù)輸出當(dāng)前編輯中的文本行。</p><p>  ■ 第四步 修改CEditorView類的OnDraw()函數(shù),編輯后該函數(shù)的代碼如下:</p><p>  void CEditorView::OnDraw(CDC* pDC)</p>

60、<p><b>  {</b></p><p>  CEditorDoc* pDoc = GetDocument();</p><p>  ASSERT_VALID(pDoc);</p><p>  TEXTMETRIC tm;</p><p>  pDC->GetTextMetrics(&tm)

61、;</p><p>  lHeight=tm.tmHeight+tm.tmExternalLeading;</p><p>  cWidth=tm.tmAveCharWidth;</p><p><b>  int y=0;</b></p><p>  POSITION pos;</p><p>

62、  CString line;</p><p>  if(!(pos=pDoc->lines.GetHeadPosition()))</p><p><b>  {</b></p><p><b>  return;</b></p><p><b>  }</b><

63、/p><p>  while(pos!=NULL)</p><p><b>  {</b></p><p>  line=pDoc->lines.GetNext(pos);</p><p>  pDC->TextOut(0, y, line, line.GetLength());</p><p

64、>  y+=lHeight;</p><p><b>  }</b></p><p><b>  }</b></p><p>  在OnDraw()函數(shù)中,首先調(diào)用GetDocument()函數(shù),取得指向當(dāng)前視圖所對(duì)應(yīng)的文檔的指針。通過(guò)這個(gè)指針,來(lái)訪問(wèn)文檔中的數(shù)據(jù)。以后在視圖中修改文檔中的數(shù)據(jù),也是通過(guò)GetDocu

65、ment()來(lái)取得文檔指針,再通過(guò)該文檔指針修改文檔中的數(shù)據(jù)。</p><p>  ■ 第五步 編譯運(yùn)行,結(jié)果如圖8.13所示。</p><p>  圖8.13 Editor的運(yùn)行結(jié)果</p><p>  【例8.3】一個(gè)簡(jiǎn)單的文檔序列化示例(Ex_SDIArchive)。</p><p>  ■ 第一步 用MFCAppWizard(exe

66、)創(chuàng)建一個(gè)默認(rèn)的單文檔應(yīng)用程序Ex_SDIArchive。</p><p>  ■ 第二步 打開(kāi)StringTable資源,將文檔模板字符串資源IDR_MAINFRAME內(nèi)容修改為:文檔序列化操作\n\n\n自定義文件(*.my)\n.my\nExSDIArchive.Document\nEx_SDI Document。如圖8.16所示。</p><p>  圖8.16 文檔模板字符串的

67、設(shè)置</p><p>  ■ 第三步 為CEx_SDIArchiveDoc類添加下列成員變量:</p><p>  class CEx_SDIArchiveDoc : public CDocument</p><p><b>  {</b></p><p><b>  ……</b></p>

68、;<p>  public: CPoint points[100]; int m_index; // 表示數(shù)組中點(diǎn)的數(shù)目;</p><p><b>  ……</b></p><p><b>  }</b></p><p>  ■ 第四步 在CExSDIArchiveDoc::OnNewDocu

69、ment函數(shù)中添加下列代碼:m_index=0;</p><p>  BOOL CEx_SDIArchiveDoc::OnNewDocument()</p><p><b>  {</b></p><p><b>  ……</b></p><p>  m_index=0;return TRUE;&

70、lt;/p><p><b>  }</b></p><p>  ■ 第五步 用MFC ClassWizard為類CEx_SDIArchiveView添加WM_LBUTTONDOWN的消息處理函數(shù)OnLButtonDown(),如圖8.17所示。然后打開(kāi)該函數(shù)進(jìn)行編輯。修改后的OnLButtonDown函數(shù)如下:</p><p>  void CEx

71、_SDIArchiveView::OnLButtonDown(UINT nFlags, CPoint point) </p><p><b>  {</b></p><p>  CEx_SDIArchiveDoc* pDoc=GetDocument();</p><p>  if(pDoc->m_index==100)return;

72、</p><p>  pDoc->m_index++;</p><p>  pDoc->points[pDoc->m_index]=point; // 接受鼠標(biāo)輸入,將其添加到文檔類</p><p>  pDoc->SetModifiedFlag(); // 設(shè)置文檔修改標(biāo)志</p><p&

73、gt;  Invalidate(); // 更新客戶區(qū)域</p><p>  CView::OnLButtonDown(nFlags, point);</p><p><b>  }</b></p><p>  圖8.17 為視圖類添加WM_LBUTTONDOWN的消息處理函數(shù)</p>

74、;<p>  ■ 第六步 修改CEx_SDIArchiveView CEditorView類的OnDraw()函數(shù),編輯后該函數(shù)的代碼如下:</p><p>  void CEx_SDIArchiveView::OnDraw(CDC* pDC)</p><p><b>  {</b></p><p><b>  ……&l

75、t;/b></p><p>  int index;</p><p>  index=pDoc->m_index;</p><p>  for (int i=1;i<=index;i++)</p><p>  pDC->Ellipse(pDoc->points[i].x-2,pDoc->points[i].

76、y-2,</p><p>  pDoc->points[i].x+2,pDoc->points[i].y+2);</p><p><b>  }</b></p><p>  ■ 第七步 用MFC ClassWizard為類CEx_SDIArchiveDoc添加Serialize虛函數(shù),實(shí)現(xiàn)文檔類中成員添加下列代碼:</p>

77、;<p>  void CEx_SDIArchiveDoc::Serialize(CArchive& ar)</p><p><b>  {</b></p><p>  if (ar.IsStoring())</p><p><b>  {</b></p><p>  ar&l

78、t;<m_index;</p><p>  for (int i=0;i<=m_index;i++)</p><p>  ar<<points[i].x<<points[i].y; </p><p><b>  }</b></p><p><b>  else</b&g

79、t;</p><p><b>  {</b></p><p>  ar>>m_index;</p><p>  for (int i=0;i<=m_index;i++)</p><p>  ar>>points[i].x>>points[i].y;</p><

80、p><b>  }</b></p><p><b>  }</b></p><p>  ■ 第八步 編譯運(yùn)行并測(cè)試。結(jié)果如圖8.18所示。程序運(yùn)行后,選擇【文件】【另存為】命令,指定一個(gè)文檔名ab,然后選擇【文件】【新建】命令,再打開(kāi)文檔,結(jié)果就會(huì)彈出對(duì)話框,顯示該文檔的內(nèi)容。</p><p>  圖8.18 E

81、x_SDIArchive的運(yùn)行結(jié)果</p><p>  【例8.4】一個(gè)簡(jiǎn)單的CArchive類用法的示例(Ex_Archive)。</p><p>  ■ 第一步 用MFC AppWizard(exe)創(chuàng)建一個(gè)默認(rèn)的基于對(duì)話框的應(yīng)用程序Ex_Archive。</p><p>  ■ 第二步 選擇【文件】【新建】命令,顯示出“新建”對(duì)話框。單擊“文件”標(biāo)簽在左邊的列

82、表框中選擇C/C++ Header File項(xiàng),在右邊的“文件”下的編輯框中鍵入Person.h,單擊【確定】按鈕,如圖8.19所示。在Person.h文件中輸入下面的代碼:</p><p>  class CPerson : public CObject</p><p><b>  {</b></p><p>  DECLARE_SERIAL

83、(CPerson)</p><p><b>  public:</b></p><p>  UINT Load(void);</p><p>  CString m_szName ;</p><p>  UINT m_nAge;</p><p>  virtual void Serialize(C

84、Archive& ar);</p><p>  CPerson(); </p><p>  virtual ~CPerson();</p><p><b>  };</b></p><p>  圖8.19 新建頭文件</p><p>  ■ 第三步 同上步,選擇【文件】【新建】命令,

85、顯示出“新建”對(duì)話框。單擊“文件”標(biāo)簽,在左邊的列表框中選擇C++ Source File項(xiàng),在右邊的“文件”下的編輯框中輸入Person.cp,單擊【確定】按鈕。在Person.cpp文件中輸入下面的代碼:</p><p>  #include "stdafx.h"</p><p>  #include "Person.h"</p>

86、<p>  IMPLEMENT_SERIAL(CPerson, CObject, 1)</p><p>  CPerson::CPerson()</p><p><b>  { }</b></p><p>  CPerson::~CPerson()</p><p><b>  { }<

87、;/b></p><p>  void CPerson::Serialize(CArchive& ar) </p><p><b>  {</b></p><p>  if (ar.IsStoring())ar<<m_szName<<m_nAge;</p><p>  else

88、 ar>>m_szName>>m_nAge;</p><p><b>  } </b></p><p>  UINT CPerson::Load()</p><p><b>  {</b></p><p><b>  CFile f;

89、</b></p><p>  char buf[512];</p><p>  if( !f.Open( "person.dat", CFile::shareDenyWrite|CFile::modeRead) ) return 0;</p><p><b>  else {</b></p>&

90、lt;p>  CArchive ar( &f, CArchive::load, 512, buf );</p><p>  Serialize(ar);return 1;</p><p><b>  }</b></p><p><b>  }</b></p><p>  說(shuō)明:通過(guò)

91、2、3兩步建立了CPerson類,并且改類為可序列化的類,CPerson類的成員函數(shù)Load( )首先生成指向"person.dat"文件的CFile對(duì)象,然后構(gòu)造讀文件的CArchive對(duì)象ar,并從文件中讀數(shù)據(jù)完成Cperson對(duì)象的初始化。</p><p>  ■ 第四步 編輯IDD_EX_ARCHIVE_DIALOG對(duì)話框資源,如圖8.20所示。</p><p>

92、;  圖8.20 對(duì)話框資源</p><p>  設(shè)置圖8.20控件的屬性如表8.3示:</p><p>  表8.3 添加的控件</p><p>  ■ 第五步 打開(kāi)MFC ClassWizard的Member Variable頁(yè)面,確定class Name是CEx_ArchiveDlg,選中所需的控件ID號(hào),雙擊鼠標(biāo)。依次為下列控件添加成員變量,如下表8.4

93、所示。</p><p>  表8.4 控件變量</p><p>  ■ 第六步 為類CEx_ArchiveDlg添加一個(gè)CPerson類的對(duì)象m_person成員。并在Ex_ArchiveDlg.h文件的頭部添加以下語(yǔ)句:</p><p>  #include "person.h"</p><p>  ■ 第七步 修改C

94、Ex_ArchiveDlg的OnInitDialog()函數(shù)在該函數(shù)中添加從文件讀取數(shù)據(jù)并初始化m_person的代碼:</p><p>  BOOL CEx_ArchiveDlg::OnInitDialog()</p><p><b>  {</b></p><p><b>  ……</b></p><

95、;p>  if(m_person.Load()){</p><p>  this->m_szName=this->m_person.m_szName;</p><p>  this->m_nAge=this->m_person.m_nAge;</p><p>  this->UpdateData(FALSE);</p>

96、<p><b>  }</b></p><p><b>  else </b></p><p>  AfxMessageBox("load person data fails");</p><p>  return TRUE; }</p><p>  ■ 第八步 用

97、MFC ClassWizard為按鈕IDC_SAVE添加BN_CLICKED的消息映射,并增加下列代碼:</p><p>  void CEx_ArchiveDlg::OnSave() </p><p><b>  {</b></p><p><b>  CFile f;</b></p><p> 

98、 char buf[512];</p><p>  if( !f.Open( "person.dat",CFile::modeCreate | CFile::modeWrite) ) {</p><p>  exit( 1 );</p><p><b>  }</b></p><p>  CArchi

99、ve ar( &f, CArchive::store, 512, buf );</p><p>  UpdateData();</p><p>  m_person.m_nAge=this->m_nAge;</p><p>  m_person.m_szName=this->m_szName;</p><p>  m_

100、person.Serialize(ar);</p><p><b>  }</b></p><p>  ■ 第九步 編譯運(yùn)行并測(cè)試。</p><p>  【例8.5】將單文檔應(yīng)用程序中的文檔窗口靜態(tài)分成3×2個(gè)窗格(Ex_Split)。</p><p>  第一步 用MFC AppWizard(exe)創(chuàng)建一個(gè)

101、單文檔應(yīng)用程序Ex_Split。</p><p>  第二步 打開(kāi)框架窗口類MainFrm.h頭文件,為CMainFrame類添加一個(gè)保護(hù)類型的切分窗口類的數(shù)據(jù)成員,如下面的定義:</p><p>  protected:</p><p>  CStatusBarm_wndStatusBar;</p><p>  CToolBarm_

102、wndToolBar;</p><p>  CSplitterWnd m_wndSplitter; // 添加的數(shù)據(jù)成員</p><p>  第三步 用MFC ClassWizard為CMainFrame類添加OnCreateClient(當(dāng)主框架窗口客戶區(qū)創(chuàng)建的時(shí)候自動(dòng)調(diào)用該函數(shù))函數(shù)重載,并添加下列代碼:</p><p>

103、;  BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) </p><p><b>  {</b></p><p>  CRect rc; GetClientRect(rc);// 獲取客戶區(qū)大小</p><p>  // 計(jì)算

104、每個(gè)窗格的平均尺寸</p><p>  CSize paneSize(rc.Width()/2-16,rc.Height()/3-16);</p><p>  m_wndSplitter.CreateStatic(this,3,2);// 創(chuàng)建3 x 2個(gè)靜態(tài)窗格</p><p>  // 為相應(yīng)的窗格指定視圖類</p><p>  

105、m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CEx_SplitView), paneSize,pContext);</p><p>  m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CEx_SplitView),paneSize,pContext);</p><p>  m_wndSplitter.Creat

106、eView(1,0,RUNTIME_CLASS(CEx_SplitView), paneSize,pContext);</p><p>  m_wndSplitter.CreateView(1,1,RUNTIME_CLASS(CEx_SplitView),paneSize,pContext);</p><p>  m_wndSplitter.CreateView(2,0,RUNTIME_C

107、LASS(CEx_SplitView), paneSize,pContext);</p><p>  m_wndSplitter.CreateView(2,1,RUNTIME_CLASS(CEx_SplitView),paneSize,pContext);</p><p>  return TRUE;</p><p><b>  }</b>&l

108、t;/p><p>  說(shuō)明:在靜態(tài)切分窗口的生成過(guò)程中CMainFrame類的相關(guān)成員函數(shù)的調(diào)用工程如圖8.21所示。</p><p>  圖8.21 靜態(tài)切分窗口的生成過(guò)程</p><p>  第四步 在MainFrm.cpp源文件的開(kāi)始處,添加視圖類CEx_SplitView的包含文件:</p><p>  #include "E

109、x_SplitView.h"</p><p>  第五步 在Ex_SplitView.h頭文件的開(kāi)始處,在class CEx_SplitView : public CView語(yǔ)句前面添加下列代碼:</p><p>  class CEx_SplitDoc;</p><p>  第六步 修改CEx_SplitView::OnDraw ()函數(shù),編輯后該函數(shù)

110、的代碼如下:</p><p>  void CEx_SplitView::OnDraw(CDC* pDC)</p><p><b>  {</b></p><p>  CEx_SplitDoc* pDoc = GetDocument();</p><p>  ASSERT_VALID(pDoc);</p>

111、<p>  pDC->TextOut(0,0,"Hello World!");</p><p><b>  }</b></p><p>  第七步 編譯并運(yùn)行,結(jié)果如圖8.22所示。</p><p>  圖8.22 Ex_Split的運(yùn)行結(jié)果</p><p>  【例8.6】靜態(tài)切分

112、窗口的多視圖SDI應(yīng)用程序(Ex_SplitSDI)。</p><p>  (1)創(chuàng)建一個(gè)默認(rèn)的單文檔應(yīng)用程序Ex_SplitSDI</p><p>  第一步 用MFC AppWizard(exe)創(chuàng)建一個(gè)單文檔應(yīng)用程序Ex_SplitSDI。</p><p>  (2)增加文檔類數(shù)據(jù)成員</p><p>  第一步 為文檔類添加集合類成員

113、:</p><p>  CArray<int,int> m_nArray;</p><p>  在Ex_SplitSDIDoc.h文件的頭部,加入語(yǔ)句:</p><p>  #include <afxtempl.h></p><p>  第二步 在CEx_SplitSDIDoc::OnNewDocument()函數(shù)中,

114、初始化數(shù)據(jù)成員m_nArray:</p><p>  BOOL CEx_SplitSDIDoc::OnNewDocument()</p><p><b>  {</b></p><p><b>  ……</b></p><p>  m_nArray.SetSize(10,0);</p>

115、<p>  m_nArray[0]=10; m_nArray[1]=5;</p><p>  m_nArray[2]=7; m_nArray[3]=23;</p><p>  m_nArray[4]=14; m_nArray[5]=16;</p><p>  m_nArray[6]

116、=10; m_nArray[7]=7;</p><p>  m_nArray[8]=9; m_nArray[9]=6;</p><p>  return TRUE;</p><p><b>  }</b></p><p>  第三步 修改CEx_SplitSDIView::

117、OnDraw()函數(shù),編輯后該函數(shù)的代碼如下:</p><p>  void CEx_SplitSDIView::OnDraw(CDC* pDC)</p><p><b>  {</b></p><p>  CEx_SplitSDIDoc* pDoc = GetDocument();</p><p>  ASSERT_V

118、ALID(pDoc);</p><p>  TEXTMETRIC tm;</p><p>  pDC->GetTextMetrics(&tm);</p><p>  int y=0; char str[20];</p><p>  for(int i=0;i<pDoc->m_nArray.GetSize

119、();i++)</p><p><b>  {</b></p><p>  wsprintf(str,"%d: %d",i+1,pDoc->m_nArray[i]);</p><p>  pDC->TextOut(0,y,str);</p><p>  y+=tm.tmHeight+

120、tm.tmExternalLeading;</p><p><b>  }</b></p><p><b>  }</b></p><p>  (3)增加一個(gè)新的視圖類CBarView</p><p>  第一步 在Visual C++中,選擇菜單【插入】【新建類】命令,打開(kāi)新建類對(duì)話框。在“Cla

121、ss type”組合框中選擇MFC Class,類名為CBarView,默認(rèn)的類文件為BarView.cpp。設(shè)置該類的父類為CView,如圖8.23所示。</p><p>  圖8.23 New Class對(duì)話框</p><p>  第二步 在BarView.h文件中,在類CBarView的定義中添加如下代碼:</p><p>  CEx_SplitSDIDoc

122、* GetDocument();</p><p>  在BarView.h文件的頭部,加入以下語(yǔ)句:</p><p>  #include "Ex_SplitSDIDoc.h"</p><p>  第三步 在BarView.cpp文件中,添加類CBarView::GetDocument()的實(shí)現(xiàn)函數(shù):</p><p> 

123、 CEx_SplitSDIDoc* CBarView::GetDocument() </p><p><b>  {</b></p><p>  ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEx_SplitSDIDoc)));</p><p>  return (CEx_SplitSDIDoc*

124、)m_pDocument;</p><p><b>  }</b></p><p>  第四步 修改CBarView::OnDraw()函數(shù),編輯后該函數(shù)的代碼如下:</p><p>  void CBarView::OnDraw(CDC* pDC)</p><p><b>  {</b></

125、p><p>  CEx_SplitSDIDoc* pDoc = GetDocument();</p><p>  CRect rc; </p><p>  int cBar,cBarSpace,x,y;</p><p>  int cxGraph=100;int cyGraph=20;</p><p>  GetC

126、lientRect(&rc);</p><p>  CBrush br1(RGB(255,0,0));</p><p>  CPen pen(PS_SOLID,1,RGB(255,0,0));</p><p>  CBrush *poldbr=pDC->SelectObject(&br1);</p><p>  CPen

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(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)論