一、多文档视图构架程序
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; }
运行结果:
伪代码:
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;
}
}
}
}