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;

        }

      }  

    }

  }  

原文地址:https://www.cnblogs.com/csqtech/p/5699822.html