八宝书库 > 文学其他电子书 > 深入浅出MFC第2版(PDF格式) >

第87部分

深入浅出MFC第2版(PDF格式)-第87部分

小说: 深入浅出MFC第2版(PDF格式) 字数: 每页4000字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




#0089 

#0090 static UINT indicators'' = 

#0091 { 

#0092     ID_SEPARATOR; 

#0093     ID_INDICATOR_CAPS; 

#0094     ID_INDICATOR_NUM; 

#0095     ID_INDICATOR_SCRL; 

#0096 }; 

#0097 

#0098 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)   

#0099 { 

#0100     m_wndToolBar。Create(this); 



#0101     m_wndToolBar。LoadToolBar(IDR_MAINFRAME);  

#0102     m_wndStatusBar。Create(this); 



#0103     m_wndStatusBar。SetIndicators(indicators;  

#0104               sizeof(indicators)/sizeof(UINT)); 

#0105 

#0106     m_wndToolBar。SetBarStyle(m_wndToolBar。GetBarStyle() | 

#0107             CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); 

#0108 

#0109     m_wndToolBar。EnableDocking(CBRS_ALIGN_ANY); 



                                                                                 427 


…………………………………………………………Page 490……………………………………………………………

                   第篇    湷觥 FC  程式設計 



                   #0110     EnableDocking(CBRS_ALIGN_ANY); 

                   #0111     DockControlBar(&m_wndToolBar); 

                   #0112     return 0; 

                   #0113 } 

                   #0114 

                   #0115 IMPLEMENT_DYNCREATE(CChildFrame; CMDIChildWnd) 

                   #0116 

                   #0117 BEGIN_MESSAGE_MAP(CChildFrame; CMDIChildWnd) 

                   #0118 END_MESSAGE_MAP() 

                   #0119 

                   #0120 IMPLEMENT_DYNCREATE(CScribbleDoc; CDocument) 

                   #0121 

                   #0122 BEGIN_MESSAGE_MAP(CScribbleDoc; CDocument) 

                   #0123 END_MESSAGE_MAP() 

                   #0124 

                   #0125 void CScribbleDoc::Serialize(CArchive& ar)   

                   #0126 { 

                   #0127     if (ar。IsStoring()) 

                   #0128     { 

                   #0129             // TODO: add storing code here 

                   #0130     } 

                   #0131     else 

                   #0132     { 

                   #0133             // TODO: add loading code here 

                   #0134     } 

                   #0135 } 

                   #0136 

                   #0137 IMPLEMENT_DYNCREATE(CScribbleView; CView) 

                   #0138 

                   #0139 BEGIN_MESSAGE_MAP(CScribbleView; CView) 

                   #0140     ON_MAND(ID_FILE_PRINT; CView::OnFilePrint) 

                   #0141     ON_MAND(ID_FILE_PRINT_DIRECT; CView::OnFilePrint) 

                   #0142     ON_MAND(ID_FILE_PRINT_PREVIEW; CView::OnFilePrintPreview) 

                   #0143 END_MESSAGE_MAP() 

                   #0144 

                   #0145 void CScribbleView::OnDraw(CDC* pDC) 

                   #0146 { 

                   #0147     CScribbleDoc* pDoc = GetDocument(); 

                   #0148     // TODO: add draw code for native data here 

                   #0149 } 



                      图7…6 Scribble step0 执行时序。这是一张简图,有一些次要动作 ( 例如鼠 



                             标拉曳功能、设定对话框底色) 并未列出, 但是在稍后的细部讨论中 



                             会提到。 



428 


…………………………………………………………Page 491……………………………………………………………

                                        第7章    簡單而完整:MFC 骨幹程式 



以下是图7…6 程序流程之说明: 



   

  ~  动作与流程和前一章的Hello 程序如出一辙。 



  我们改写InitInstance 这个虚拟函数。 



  new 一个CMultiDocTemplate 对象,此对象规划Document 、View  以及Document 

   Frame 窗口三者之关系。 



  new 一个CMyMDIFrameWnd 对象,做为主窗口对象。 



  调用LoadFrame,产生主窗口并加挂菜单等诸元,并指定窗口标题、文件标题、文 



   件档扩展名等(关键在IDR_MAINFRAME 常数)。LoadFrame  内部将调用Create,后 



   者将调用CreateWindowEx,于是触发WM_CREATE 消息。 



  由于我们曾于CMainFrame 之中拦截WM_CREATE  (利用ON_WM_CREATE 宏), 



   所以WM_CREATE 产生之际Framework 会调用OnCreate。我们在此为主窗口挂上工具 



   列和状态列。 



  回到InitInstance ,执行ShowWindow 显示窗口。 



 InitInstance  结束,回到AfxWinMain ,执行Run ,进入消息循环。其间的黑盒子已 



  在上一章的Hello 范例中挖掘过。 



 消息经由Message Routing 机制,在各类别的Message Map 中寻求其处理例程。 



   WM_MAND/ID_FILE_OPEN  消息将由CWinApp::OnFileOpen 函数处理。此函数由 



   MFC 提供,它在显示过【File Open 】对话框后调用Serialize  函数。 



  我们改写Serialize  函数以进行我们自己的文件读写动作。 



  WM_MAND/ID_APP_ABOUT  消息将由OnAppAbout 函数处理。 



  OnAppAbout 函数利用CDialog 的性质很方便地产生一个对话框。 



                                                                      429 


…………………………………………………………Page 492……………………………………………………………

                  第篇    湷觥 FC  程式設計 



             Document Template 的意义 



                   Document Template 是一个全新的观念。 



                   稍早我已提过Document/View  的概念,它们互为表里。View 本身虽然已经是一个窗口, 



                   其外围却必须再包装一个外框窗口做为舞台。这样的切割其实是为了让View 可以非常独 



                   立地放置于「MDI Document Frame 窗口」或「SDI Document Frame 窗口」或「OLE Document 



                   Frame 窗口」等各种应用之中。也可以说,Document Frame 窗口是View 窗口的一个容 



                   器。资料的内容、资料的表象、以及「容纳资料表象之外框窗口」三者是一体的,换言 



                   之,程序每打开一份文件(资料),就应该产生三份对象: 



                   1。 一份Document 对象, 



                   2。 一份View 对象, 



                   3。 一份CMDIChildWnd 对象(做为外框窗口) 



                   这三份对象由一个所谓的Document Template 对象来管理。让这三份对象产生关系的关 



                   键在于CMultiDocTemplate: 



                      BOOL CScribbleApp::InitInstance() 

                      { 

                          。。。 

                          CMultiDocTemplate* pDocTemplate; 

                          pDocTemplate = new CMultiDocTemplate( 

                                  IDR_SCRIBTYPE; 

                                  RUNTIME_CLASS(CScribbleDoc); 

                                  RUNTIME_CLASS(CChildFrame); 

                                  RUNTIME_CLASS(CScribbleView)); 

                          AddDocTemplate(pDocTemplate); 

                          。。。 

                      } 



                    如果程序支持不同的资料格式(例如一为TEXT 一为BITMAP ),那么就需要不同的 



                  Document Template  : 



430 


…………………………………………………………Page 493……………………………………………………………

                                              第7章    簡單而完整:MFC 骨幹程式 



BOOL CMyWinApp::InitInstance() 

 { 

  。。。 

  CMultiDocTemplate* pDocTemplate; 



  pDocTemplate = new CMultiDocTemplate( 

            IDR_TEXTTYPE; 

            RUNTIME_CLASS(CTextDoc); 

            RUNTIME_CLASS(CChildFrame); 

            RUNTIME_CLASS(CTextView)); 

  AddDocTemplate(pDocTemplate); 



  pDocTemplate = new CMultiDocTemplate( 

            IDR_BMPTYPE; 

            RUNTIME_CLASS(CBmpDoc); 

            RUNTIME_CLASS(CChildFrame); 

            RUNTIME_CLASS(CBmpView)); 

  AddDocTemplate(pDocTemplate); 

  。。。 

 } 



这其中有许多值得讨论的地方,而CMultiDocTemplate 的构造式参数透露了一些端倪: 



CMultiDocTemplate::CMultiDocTemplate(UINT nIDResource; 

                                            CRuntimeClass* pDocClass; 

                                            CRuntimeClass* pFrameClass; 

                                            CRuntimeClass* pViewClass); 



1。 nIDResource :这是一个资源ID ,表示此一文件类型(文件格式)所使用的资源。 

  本例为IDR_SCRIBTYPE,在RC 档中代表多种资源(不同种类的资源可使用 

  相同的ID ): 



 IDR_SCRIBTYPE ICON DISCARDABLE  〃resScribbleDoc。ico〃  



 IDR_SCRIBTYPE MENU PRELOAD DISCARDABLE  

 { 。。。 } 

 STRINGTABLE PRELOAD DISCARDABLE 

BEGIN 

   IDR_MAINFRAME 〃Scribble Step0〃 

   IDR_SCRIBTYPE 〃nScribnScribnScribble Files (*。scb)n。SCBn 

                     Scribble。DocumentnScrib Document〃 

END 

               原码太长;我把它截为两半;实际上是一整行。有七个子字符串各以'n' 



              分隔。这些子字符串完整描述文件的类型。第一个子字符串于MDI 程序 



               中用不着,故本例省略(成为空字符串)。 



                                                                                  431 


…………………………………………………………Page 494……………………………………………………………

                第篇    湷觥 FC  程式設計 



                其中的ICON 是文件窗口被最小化之后的图标;MENU 是当程序存在有任何文件 



                 窗口时所使用的菜单(如果没有开启任何文件窗口,菜单将是另外一套,稍后再述)。 



                至于字符串表格(STRINGTABLE )中的字符串,稍后我有更进一步的说明。 



                  2。 pDocClass 。这是一个指针,指向Document 类别( 衍生自CDocument)之 



                   「CRuntimeClass 对象」。 



                  3。 pFrameClass 。这是一个指针,指向Child Frame 类别(衍生自CMDIChildWnd) 



                   之「CRuntimeClass 对象」。 



                  4。 pViewClass 。这是一个指针,指向View 类别(衍生自CView)之「CRuntimeClass 



                   对象」。 



                                         CRuntimeClass 



                  我曾经在第3章「自制RTTI 」一节解释过什么是CRuntimeClass。它就是「类别型 



                  录网」串行中的元素类型。任何一个类别只要在声明时使用DECLARE_DYNAMIC 或 



                  DECLARE_DYNCREATE 或DECLARE_SERIAL 宏,就会拥有一个静态的(static ) 



                  CRuntimeClass  内嵌对象。 



                 好,你看,Document Template 接受了三种类别的CRuntimeClass 指针,于是每当使用者 



                 打开一份文件,Document Template 就能够根据「类别型录网」(第3章所述),动态生 



                 成出三个对象(document 、view 、document frame window )。如果你不记得MFC  的动态 



                 生成是怎么一回事儿,现在正是

返回目录 上一页 下一页 回到顶部 0 0

你可能喜欢的