友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

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

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


   #0046          pDC…》Rectangle(x; y; x+cxBar; y+pDoc…》m_intArray'i'); 

   #0047 

   #0048     pDC…》SelectObject(pOldPen); 

   #0049     pDC…》SelectObject(pOldBrush); 

   #0050  } 



如果你要令三个view 都有打印预视能力,必须在每一个view 类别中改写以 



 下三个虚拟函数: 



   virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); 

   virtual void OnBeginPrinting(CDC* pDC; CPrintInfo* pInfo); 

   virtual void OnEndPrinting(CDC* pDC; CPrintInfo* pInfo); 



至于其函数内容,从CGraphView 的同名函数中依样画葫芦拷贝一份过来即可。 



  本例不示范文件读写动作,所以CGraphDoc 没有改写 Serialize 虚拟函数。 



图13…3 是Graph 程序的执行画面。 



                                                                                 723 


…………………………………………………………Page 786……………………………………………………………

             第篇    深入  MFC  程式設計 



                  图13…3 Graph 执行画面。每当选按 【File/New 】 (或工具栏上的对应按 



                       钮)打开一份新文件,其内就有10 笔整数资料。你可选按 【Graph 



                       Data 】 (或工具栏上的对应按钮) 改变资料内容。 



        静态分裂窗口之观念整理 



              我想你已经从前述的OnCreateClient 函数中认识了静态分裂窗口的相关函数。我可以用 



              图13…4 解释各个类别的关系与运用。 



              基本上图13…4 三个窗口可以视为三个完全独立的view 窗口,有各自的类别,以各自的 



              方式显示资料。不过,资料倒是来自同一份Document 。试试看预视效果,你会发现,哪 



              一个窗口为「作用中」,哪一个窗口的绘图动作就主宰预视窗口。你可以利用SetActivePane 



              设定作用中的窗口,也可以调用GetActivePane 获得作用中的窗口。但是,你会发现, 



              从外观上很难看出哪一个窗口是「作用中的」窗口。 



724 


…………………………………………………………Page 787……………………………………………………………

                                                  第 13 章    多重文件與多重顯示 



      CChildFrame 对象(Document Frame 窗口) 



                    CSplitterWnd 对象(类似SDK MDI 程序中的Client 窗口, 



                    用于幕后协调而不显现),图中以虚框表示。 



                                         由CSplitterWnd::CreateView 产 



                                         生的view  窗口,以CBarView 



            由CSplitterWnd::CreateView 产生的 为基础。 



            view  窗口,以CTextView 为基础。 



                                        由CSplitterWnd::CreateView 产生 



                                        的view  窗口,以CGraphView 为 



                                       基础。 



                图13…4 静态分裂窗口的类别运用 (以Graph 为例) 



同源子窗口 



       虽然我说静态分裂窗口的窗口可视为完全独立的view 窗口,但毕竟它们不是!它们还 



       框在一个大窗口中。如果你不喜欢分裂窗口(谁知道呢,当初我也不太喜欢),我们来 



       试点新鲜的。 



       点子是从【Window/New Window 】开始。这个菜单项目令Framework 为我们做出目前作 



       用中的view 窗口的另一份拷贝。如果我们能够知道Framework 是如何动作,是不是可 



       以引导它使用另一个view 类别,以不同的方式表现同一份资料? 



       这就又有偷窥源代码的需要了。MFC 并没有提供正常的管道让我们这么做,我们需要 



       MFC 源代码。 



                                                                            725 


…………………………………………………………Page 788……………………………………………………………

                   第篇    深入  MFC  程式設計 



             CMDIFrameWnd::OnWindowNew 



                   如果你想在程序中设计断点,一步一步找出【Window/New Window 】的动作,就像我 



                   在第12 章对付OnFilePrint 和OnFilePrintPreview 一样,那么你会发现没有着力点,因 



                   为AppWizard 并不会做出像这样的消息映射表格: 



                       BEGIN_MESSAGE_MAP(CScribbleView; CScrollView) 

                           。。。 

                           ON_MAND(ID_FILE_PRINT; CView::OnFilePrint) 

                           ON_MAND(ID_FILE_PRINT_PREVIEW; CView::OnFilePrintPreview) 

                       END_MESSAGE_MAP() 



                   你根本不知道【Window/New Window 】这个命令流到哪里去了。第7章的「标准菜单File 



                   / Edit / View / Window / Help 」一节,也曾说过这个命令项是属于「与Framework 预有关 



                   联型」的。 



                   那么我如何察其流程?1/3 用猜的,1/3 靠字符串搜寻工具GREP                       (第8章介绍过),1/3 靠 



                   勤读书。然后我发现,【New Window 】命令流到CMDIFrameWnd::OnWindowNew 去了。 



                   图13…5 是其源代码(MFC 4。0  的版本)。 



                   #0001  void CMDIFrameWnd::OnWindowNew() 

                   #0002  { 

                   #0003      CMDIChildWnd* pActiveChild = MDIGetActive(); 

                   #0004      CDocument* pDocument; 

                   #0005      if (pActiveChild == NULL || 

                   #0006        (pDocument = pActiveChild…》GetActiveDocument()) == NULL) 

                   #0007      { 

                   #0008              TRACE0(〃Warning: No active document for WindowNew mand。n〃); 

                   #0009              AfxMessageBox(AFX_IDP_MAND_FAILURE); 

                   #0010              return;     // mand failed 

                   #0011      } 

                   #0012 

                   #0013      // otherwise we have a new frame ! 

                   #0014      CDocTemplate* pTemplate = pDocument…》GetDocTemplate(); 

                   #0015      ASSERT_VALID(pTemplate); 

                   #0016      CFrameWnd* pFrame = pTemplate…》CreateNewFrame(pDocument; pActiveChild); 

                   #0017      if (pFrame == NULL) 

                   #0018      { 

                   #0019              TRACE0(〃Warning: failed to create new frame。n〃); 



726 


…………………………………………………………Page 789……………………………………………………………

                                                  第 13 章    多重文件與多重顯示 



    #0020        return; // mand failed 



    #0021      } 



    #0022 



    #0023   pTemplate…》InitialUpdateFrame(pFrame; pDocument); 



    #0024 } 



          图13…5 CMDIFrameWnd::OnWindowNew 源代码 (  in WINMDI。CPP) 



    我们的焦点放在CMDIFrameWnd::OnWindowNew 函数的第14 行,该处取得我们在 



    InitInstance  函数中做好的Document Template,而你知道,Document Template  中记录有 



    View 类别。好,如果我们能够另准备一个崭新的View 类别,有着不同的OnDraw 显 



    示方式,并再准备好另一份Document Template,记录该新的View 类别,然后改变图 



    13…5 的第14 行,让它使用这新的Document Template,大功成矣。 



    当然,我们绝不是要去改MFC 源代码,而是要改写虚拟函数OnWindowNew,使为我 



    们所用。这很简单,我只要把【Window / New Window 】命令项改变名称,例如改为【Window 



    / New Hex Window 】,然后为它撰写命令处理函数,函数内容完全仿照图13…5,但把第 



    14 行改设定为新的Document Template  即可。 



Text  范例程序 



    Text 程序提供【Window / New Text Window 】和【Window / New Hex Window 】两个新的 



    菜单命令项目,都可以产生出view 窗口,一个以ASCII 型式显示资料,一个以Hex 型 



    式显示资料,资料来自同一份Document 。 



     以下Text 程序的是制作过程: 



     ■进入AppWizard ,制造一个Text 项目,采用各种预设的选项。获得的主要类 



       别如下: 



                                                                             727 


…………………………………………………………Page 790……………………………………………………………

                  第篇    深入  MFC  程式設計 



                      类别           基础类别              文件 



                     CTextApp       CWinApp            TEXT。CPP            TEXT。H 



                     CMainFrame     CMDIFrameWnd       MAINFRM。CPP      MAINFRM。H 



                     CChildFrame    CMDIChildWnd       CHILDFRM。CPP    CHILDFRM。H 



                     CTextDoc       CDocument          TEXTDOC。CPP      TEXTDOC。H 



                     CTextView      CView              TEXTVIEW。CPP    TEXTVIEW。H 



                   进入整合环境中的Resource View 窗口,选择IDR_TEXTTYPE 菜单,在 



                    【Window 】菜单中加入两个新命令项: 



                       命令项目名称         识别码(ID )         提示字符串 



                     New Text Window    ID_ WINDO W_ TEXT   New a Text Window with Active Document 



                     New Hex Window     ID_ WINDO W_HEX     New a Hex Window with Active Document 



                   再在Resource View 窗口中选择IDR_MAINFRAME 工具栏,增加两个按钮,安 



                    排在Help 按钮之后: 



                     这两个按钮分别对应于新添加的两个菜单命令项目。 



                   进入ClassWizard,为两个UI 对象制作 Message Map 。这两个命令消息并不 



                    会影响Document  内容(不像上一节的GRAPH 例那样),我们在CMainFrame 



                    中处理这两个命令消息颇为恰当。 



                        UI  对象                消息                  消息处理函数 



                     ID_WINDOW_TEXT          MAND               OnWindowText 



                     ID_WINDOW_HEX           MAND               OnWindowHex 



728 


…………………………………………………………Page 791……………………………………………………………

                                                             第  13 章    多重文件與多重顯示 



利用ClassWizard 产生一个新类别,准备做为同源子窗口的第二个View 类别: 



     



  类别名称         基础类别                   文件 



    CHexView            CView                    HEXVIEW。CPP    HEXVIEW。H 



 修改程序代码,分别为两个view 类别都做出对应的Docment Template: 



    // in TEXT。H 

    class CTextApp : public CWinApp 

    { 

   public: 

           CMultiDocTemplate* m_pTemplateTxt; 

           CMultiDocTemplate* m_pTemplateHex; 

           。。。 

           public: 

           virtual BOOL InitInstance(); 

           virtual int  ExitInstance(); 

           。。。 

    }; 



    // in TEXT。CPP 

    。。。 

    #include 〃TextView。h〃 

    #include 〃HexView。h〃 

    。。。 

   BOOL CTextApp::InitInstance() 

    { 

           。。。 

           CMultiDocTemplate* pDocTemplate; 

           pDocTemplate = new CMultiDocTemplate( 

                   IDR_TEXTTYPE; 

                   RUNTIME_CLASS(CTextDoc); 

                   RUNTIME_CLASS(CChildFrame); // custom MDI child frame 

                   RUNTIME_CLASS(CTextView)); 

           AddDocTemplate(pDocTemplate); 



           m_pTemplateTxt = new CMultiDocTemplate( 

                   IDR_TEXTTYPE; 

                   RUNTIME_CLASS(CTextDoc); 

                   RUNTIME_CLASS(CChildFrame); // custom MDI child frame 

                   RUNTIME_CLASS(CTextView)); 



           m_pTemplateHex = new CMultiDocTemplate( 



                                                                                                729 


…………………………………………………………Page 792……………………………………………………………

                    第篇    深入  MFC  程式設計 



                    
返回目录 上一页 下一页 回到顶部 0 0
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!