• 8.MFC多文档视图构架程序


    一、多文档视图构架程序

      1.相关问题

        可以同时管理多个文档(可以有多个文档类对象)

      2.相关类

        CWinApp / CDocument / CView / CMIDChildWnd / CMIDFrameWnd

        CDocTemplate   

        CMultiDocTemplate - 多文档模板类

        CDocManager - 文档管理类

      3.关系图

        theApp

          |-->m_pDocManager  //文档管理类对象地址

               |-->m_templateList  //多文档模板类对象地址

                  |-->CMultiDocTemplate

                      |-->m_docList          //保存文档类对象地址

                      |-->m_pDocClass     //文档类静态变量地址,RUNTIME_CLASS( CMyDoc )

                      |-->m_pFrameClass  //子框架静态变量地址,RUNTIME_CLASS( CMyChild )

                      |-->m_pViewClass    //视图类静态变量地址,RUNTIME_CLASS( CMyView )

      相关代码:点击菜单,更新第三个个子窗口的第一个视图

    #include "stdafx.h"
    
    
    class CMyDoc : public CDocument
    {
        DECLARE_DYNCREATE(CMyDoc)
    public:
        CString m_strDoc;
    };
    IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
    
    class CMyView : public CEditView
    {
        DECLARE_DYNCREATE(CMyView)
    public:
        virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
    };
    IMPLEMENT_DYNCREATE(CMyView, CEditView)
    
    void CMyView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
    {
        CMyDoc *pDoc = (CMyDoc*)this->m_pDocument;
        this->SetWindowTextW(pDoc->m_strDoc);
    }
    
    class CMyChild : public CMDIChildWnd
    {
        DECLARE_DYNCREATE(CMyChild)
    public:
        virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
    private:
        CSplitterWnd m_split;
    };
    IMPLEMENT_DYNCREATE(CMyChild, CMDIChildWnd)
    
    BOOL CMyChild::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
        m_split.CreateStatic(this, 1, 2);
        m_split.CreateView(0, 0, RUNTIME_CLASS(CMyView), CSize(100, 100), pContext);
        m_split.CreateView(0, 1, RUNTIME_CLASS(CMyView), CSize(100, 100), pContext);
        return TRUE;
    }
    class CMyFrameWnd : public CMDIFrameWnd
    {
    
    };
    
    class CMyWinApp: public CWinApp
    {
        DECLARE_MESSAGE_MAP()
    public:
        virtual BOOL InitInstance();
    public:
        afx_msg void OnNew();
        afx_msg void OnData();
    };
    BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)
        ON_COMMAND(ID_NEW, OnNew)
        ON_COMMAND(ID_DATA, OnData)
    END_MESSAGE_MAP()
    
    CMyWinApp theApp;
    
    void CMyWinApp::OnData()
    {
        /*
        theApp
          |-->m_pDocManager  //文档管理类对象地址
                 |-->m_templateList  //多文档模板类对象地址
                      |-->CMultiDocTemplate
                             |-->m_docList      //保存文档类对象地址
                             |-->m_pDocClass    //文档类静态变量地址,RUNTIME_CLASS( CMyDoc )
                             |-->m_pFrameClass  //子框架静态变量地址,RUNTIME_CLASS( CMyChild )
                             |-->m_pViewClass   //视图类静态变量地址,RUNTIME_CLASS( CMyView )
        
        theApp
           |->m_pMainWnd(框架类对象)
                 |->m_pViewActive(视图类对象)
                       |->m_pDocument(文档类对象)
                            |->m_viewList(视图类对象)
        
        */
        CDocManager *pManager = this->m_pDocManager;
        POSITION nPos = pManager->GetFirstDocTemplatePosition();
        CMultiDocTemplate* pTemplate = (CMultiDocTemplate*)pManager->GetNextDocTemplate(nPos);
        
        POSITION nDocPos = pTemplate->GetFirstDocPosition();
        pTemplate->GetNextDoc(nDocPos);
        pTemplate->GetNextDoc(nDocPos);
        CMyDoc* pDoc = (CMyDoc*)pTemplate->GetNextDoc(nDocPos);
        pDoc->m_strDoc = "给第三个文档类赋值";
        
        nPos = pDoc->GetFirstViewPosition();
        pDoc->GetNextView(nPos);
        CMyView* pView = (CMyView*)pDoc->GetNextView(nPos);
    
        pDoc->UpdateAllViews(pView); //参数为视图类对象,填谁不刷谁
    }
    
    void CMyWinApp::OnNew()
    {
        OnFileNew();
    }
    
    BOOL CMyWinApp::InitInstance()
    {
        CMultiDocTemplate *pTemplate = new CMultiDocTemplate(
            IDR_MENU1,
            RUNTIME_CLASS(CMyDoc),
            RUNTIME_CLASS(CMyChild),
            RUNTIME_CLASS(CMyView));
        AddDocTemplate(pTemplate);
    
        CMyFrameWnd *pFrame = new CMyFrameWnd;
        m_pMainWnd = pFrame;
        pFrame->LoadFrame(IDR_MENU2);
        pFrame->ShowWindow(SW_SHOW);
        pFrame->UpdateWindow();
    
        return TRUE;
    }
    View Code

      运行结果:

      

      伪代码:

      CMultiDocTemplate::CMultiDocTemplate( ... )

      {

        CDocTemplate( ... )  //父类构造函数

        {    

          m_pDocClass     =  pDocClass;     //文档类静态变量

          m_pFrameClass  =  pFrameClass;  //子框架静态变量

          m_pViewClass    =  pViewClass;    //视图静态变量

        }

      }

      *************************************************************************

      AddDocTemplate( ... )

      {

        m_pDocManager  =  new  CDocManager;

        m_pDocManager->AddDocTemplate( pTemplate )  //参数是多文档模板类对象地址

        {

          m_templateList.AddTail( pTemplate );

        }

      }

      *************************************************************************

      CWinApp::OnFileNew( )

      {

        m_pDocManager->OnFileNew( )

        {

          CDocTemplate*  pTemplate  =  ( CDocTemplate* )m_templateList.GetHead( );  //拿到多文档模板类对象地址

          pTemplate->OpenDocumentFile( NULL ) 

          {

            return OpenDocumentFile( ... )

            {

              CDocument* pDocument = CreateNewDocument( )  //this为多文档模板类地址

              {

                CDocument*  pDoc  =  ( CDocument* )m_pDocClass->CreateObject( );  //创建文档类对象

                AddDocument( pDoc )   //将文档类对象放到链表中

                {

                  m_docList.AddTail( pDoc );

                }

                return  pDoc;

              }

              CFrameWnd*  pFrame  =  CreateNewFrame( pDocument,  NULL )

              {        

                CCreateContext  context;

                context.m_pCurrentDoc  =  pDocument;

                context.m_pNewViewClass  =  m_pViewClass;

                context.m_pNewDocTemplate  =  this;

                CFrameWnd*  pFrame  =  ( CFrameWnd* )m_pFrameClass->CreateObject( );  //创建子框架窗口对象

                pFrame->LoadFrame( ..., &context );

                return  pFrame;

              }

              return  pDocument;

            }

          }  

        }

      }  

  • 相关阅读:
    windows下快速启动或关闭系统服务方法
    java学习-struts基础(一)
    android学习-Adapter适配器进阶
    java学习-GET方式抓取网页(UrlConnection和HttpClient)
    搜索技术的历史
    android学习-数据存储(一)-----SQLite源码分析
    Python+Tkinter 抽奖小程序
    随机生成激活码
    爬虫9:Scrapy-获取steam网站前50页游戏的url
    爬虫8:Scrapy-取内容
  • 原文地址:https://www.cnblogs.com/csqtech/p/5699822.html
Copyright © 2020-2023  润新知