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