当前位置: 首页 > article >正文

MFC程序设计(十一)单文档架构

在MFC中,文档一般用于存储数据,视图一般用于显示文档中存储的数据。因此我们常常需要将文档和视图相关联

单文档视图架构特点

单文档:只有一个文档类对象,只能存储一份数据

单文档视图架构使用

代码书写

接下来的代码中,我们会见到MFC使用动态创建机制调用类加工厂创建的三个类对象

单文档架构的程序和我们之前写的程序存在一些区别,集中在应用程序类的InitInstance函数中

预备工作

1.由于下文代码中创建单文档模板类对象时需要一个资源,因此我们添加一个菜单资源:

这是我们添加的菜单资源,ID为ID_NEW

2.单文档视图架构程序要求我们为程序窗口的标题栏写一个名字,因此我们也需要添加一个字符串资源

注意:ID是固定的,为程序标题栏的名字

代码实现

#include <afxwin.h>
#include "resource.h"
class CMyDoc : public CDocument
{
	DECLARE_DYNCREATE( CMyDoc )
};
IMPLEMENT_DYNCREATE( CMyDoc, CDocument )

class CMyView : public CView
{
	DECLARE_DYNCREATE( CMyView )
public:
	virtual void OnDraw( CDC* pDC );
};
IMPLEMENT_DYNCREATE( CMyView, CView )

void CMyView::OnDraw( CDC* pDC )
{
	pDC->TextOut( 100, 100, "我是视图窗口 " );
}

class CMyFrameWnd : public CFrameWnd
{
	DECLARE_DYNCREATE( CMyFrameWnd )
};
IMPLEMENT_DYNCREATE( CMyFrameWnd, CFrameWnd )

class CMyWinApp : public CWinApp
{
public:
	virtual BOOL InitInstance();
};
BOOL CMyWinApp::InitInstance()
{
	CSingleDocTemplate* pTemplate = new CSingleDocTemplate( IDR_MENU1, 
															RUNTIME_CLASS(CMyDoc),
															RUNTIME_CLASS(CMyFrameWnd),
															RUNTIME_CLASS(CMyView));//创建单文档模板类对象
	AddDocTemplate( pTemplate );
	OnFileNew( );
	m_pMainWnd->ShowWindow( SW_SHOW );
	m_pMainWnd->UpdateWindow( );
	return TRUE;
}

CMyWinApp theApp;

执行过程

单文档视图架构的程序执行核心在于以下变量

也就是说,核心在于涉及以上对象的代码

	CSingleDocTemplate* pTemplate = new CSingleDocTemplate( IDR_MENU1, 
															RUNTIME_CLASS(CMyDoc),
															RUNTIME_CLASS(CMyFrameWnd),
															RUNTIME_CLASS(CMyView));
	AddDocTemplate( pTemplate );
	OnFileNew( );

接下来我们来观察该代码背后的原理

//单文档架构的模板类 
CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CMyDoc),		            //文档类 类信息 
		RUNTIME_CLASS(CMyFrameWnd),      		//框架类 类信息
		RUNTIME_CLASS(CMyView));	            //视图类类信息
{
	this->m_pOnlyDoc = NULL;//唯一的文档类对象地址,此处尚未保存
	this->m_pDocClass = pDocClass;
	this->m_pFrameClass = pFrameClass;
	this->m_pViewClass = pViewClass;
	//此处的this为单文档模板类的对象
	//以上代码为单文档模板类的对象的成员变量赋值
}


this->AddDocTemplate(pDocTemplate);//内部this指针应用程序类
{
	this->m_pDocManager = new CDocManager;//应用程序类-->文档管理成员变量
	m_pDocManager->AddDocTemplate(pTemplate);//内部this指针文档管理
	{
		m_templateList.AddTail(pTemplate);//将单文档模板类对象地址放入链表中
        //此时该链表就只有刚才存入的单文档模板类对象一个成员
	}
}

//OnFileNew内部执行过程
OnFileNew( )//函数内部this为&theApp
{
  m_pDocManager->OnFileNew()//函数内部this为文档管理类对象地址
  {
    CDocTemplate* pTemplate = m_templateList.GetHead();//取出之前在链表中存入的单文档模板类对象地址
    pTemplate->OpenDocumentFile()//函数内部this为单文档模板类对象地址
    {
      OpenDocumentFile(..)//函数内部this为单文档模板类对象地址
      {
        pDocument = CreateNewDocument()//函数内部this为单文档模板类对象地址
        {
          CDocument* pDocument = m_pDocClass->CreateObject(); //类对象加工厂动态创建文档类对象,并返回对象地址。                       
          AddDocument(pDocument)//函数内部this为单文档模板类对象地址
          {
            m_pOnlyDoc = pDocument;//此时前文代码未赋值的文档类对象地址被赋值了
          }
        }
        pFrame = CreateNewFrame(pDocument..)//函数内部this为单文档模板类对象地址
        {
          CCreateContext context; 
	      ...
	      context.m_pCurrentDoc = pDocument;//文档类对象地址
	      context.m_pNewViewClass = m_pViewClass;//RUNTIME_CLASS(CMyView)
          CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject(); //动态创建框架类对象,并返回对象地址 
          pFrame->LoadFrame(...., &context);//创建框架窗口
                      //后续过程看前一天的伪代码
        }
      }
    }
  }
}


http://www.kler.cn/a/543929.html

相关文章:

  • 网络编程 day3
  • 萌新学 Python 之元组 tuple
  • 机器学习分类整理【表格版】分类角度、名称、概念、常见算法、典型案例
  • leetcode_二叉树 108. 将有序数组转换为二叉搜索树
  • RAG 在智能答疑中的探索
  • 掌握正则表达式_模式匹配的艺术
  • 从时间同步到智能调度:TSN时间敏感网络如何提升工厂安全性
  • 【Elasticsearch】Kibana Dev Tools中基础使用
  • AI前端开发:革新工作环境与团队协作
  • Java小白入门基础知识(一)
  • 基于Spring Boot的分布式网上售卖系统设计
  • 【Raqote】 0 Rust 2D图形库Raqote概览
  • AGI时代的认知重塑:人类文明的范式转移与思维革命
  • 打开Visual Studio Code的时候发现未检测到适用于linux的windows子系统,那么该问题要如何解决?
  • EffectiveC++读书笔记——item36(不要重定义继承的非虚拟函数)
  • vue中使用lodash的debounce(防抖函数)
  • 如何安装和运行Zonos:详细步骤指南
  • ES6具体有什么
  • 爬虫瑞数5.5案例:某钢材交易官网(面向对象补环境)
  • Docker 部署 MySQL-5.7 单机版
  • 13.13 Flask Web Server 架构设计与生产级实现指南:从 RESTful API 开发到高并发优化
  • 【NXP i.MX6ULL 使用】IMX6Y2C-512M-EMMC 设备树配置文档
  • Windows上在Qt中快速配置OpenCV库(最简单教程)
  • ffmpeg所有版本下载地址
  • PyTorch Lightning LightningDataModule 介绍
  • 【Linux】nmcli命令详解