mfc多文档创建新的视图

概述
mfc多文档程序启动默认创建一个文档视图,通过文件新建方式创建视图非常不方便。
本文描述了,如何根据需要,手动添加多文档视图,并且获取到文档视图的对象指针,非常方便操作。

编译环境
vs2010

多文档项目名
EUiDevelop

默认文档视图对应关系(调试确定)
使用mfc创建工程产生的代码
编译生成,启动生成程序
操作:文件->新建
这个时候,会出来一个新的文档视图界面
分析
整个应用只有一个多文档模板CMultiDocTemplate
每新建一个文档视图,产生一个CEUiDevelopDoc对象
每个CEUiDevelopDoc对象对应一个CEUiDevelopView

添加多文档模板(分析默认代码)
添加多文档模板,添加到CWinAppEx中
EUiDevelop.cpp文件中

BOOL CEUiDevelopApp::InitInstance()函数
CMultiDocTemplate* pDocTemplate;
	pDocTemplate = new CMultiDocTemplate(IDR_EUiDevelopTYPE,
		RUNTIME_CLASS(CEUiDevelopDoc),
		RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
		RUNTIME_CLASS(CEUiDevelopView));
	if (!pDocTemplate)
		return FALSE;
	AddDocTemplate(pDocTemplate);

RUNTIME_CLASS宏定义,展开是一个结构体的全局对象,本人用的是静态库。查看源码宏定义,静态库和动态库方式RUNTIME_CLASS定义不一样。

MSDN建议,RegisterShellFileTypes这个函数执行之后,模板CMultiDocTemplate不要再改动,
但是我通过调试信息,发现整个运行都没有调用CWinApp::RegisterShellFileTypes

启动默认不打开视图(修改)
启动程序默认是打开一个视图的
在添加文档模板下面有这么一些代码

CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
	
// 调度在命令行中指定的命令。如果
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
if (!ProcessShellCommand(cmdInfo))
	return FALSE;

通过单步调试跟踪,发现ProcessShellCommand这个里面创建了文档视图。
原因在于
CCommandLineInfo cmdInfo;
cmdInfo.m_nShellCommand 构造函数默认赋值为 CCommandLineInfo::FileNew

如果启动不想创建文档视图,定义下面修改默认值,
CCommandLineInfo cmdInfo;
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;

手动添加视图
我按照默认文档视图对应的方式

void CMainFrame::On32773()
{ 
	// TODO: 在此添加命令处理程序代码
	POSITION pos1 = NULL;	
	POSITION pos2 = NULL;
	POSITION pos3 = NULL;

	CDocument* doc = NULL;
	CView* view = NULL;
	CFrameWnd* frame = NULL;
	CDocTemplate* docTmp = NULL;

	pos1 = theApp.GetFirstDocTemplatePosition();
	if (pos1 == NULL) { 
		goto EXIT_FUN;
	}

	docTmp = theApp.GetNextDocTemplate(pos1);//这个就是以上步骤中的pDocTemplate

	doc = docTmp->CreateNewDocument();//使用这个模板创建文档CEUiDevelopDoc
	frame = docTmp->CreateNewFrame(doc, NULL);//使用这个模板创建CChildFrame
	doc->SetTitle("987654");//视图标签上的文本
	docTmp->InitialUpdateFrame(frame, NULL, TRUE);//创建视图CEUiDevelopView显示

	/* 如下获取视图指针 */
	pos3 = doc->GetFirstViewPosition();
	while (pos3) { 
		//如下view就是创建出来的CEUiDevelopView,有且仅有一个
		view = doc->GetNextView(pos3);
	}

EXIT_FUN:
	return;
}

切换视图

CFrameWnd* fr = NULL;
CMFCTabCtrl* tab = NULL;

fr = m_View->GetParentFrame();
tab = ((CChildFrame*)fr)->GetRelatedTabGroup();
tab->SetActiveTab(0);

小结
本人花了两三天时间,稍微研究文档视图结构,只为解决目前的问题,分享给大家。不够深入,难免有理解不到位的地方。

    原文作者:shenweihong
    原文地址: https://blog.csdn.net/shenweihong/article/details/112288663
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞