MFC MDI项目多文档的创建

条件:

首先项目是采用VS向导自动创建的MDI项目。

默认情况下,MDI项目具有以下几个类:

1、基于CwinApp的App类。

2、基于CMDIFrameWnd的框架类。

3、基于CMDIChildWnd的文档框架类。

4、基于CDocument的文档类。

5、基于CView的视图类。

一个空的MDI项目在创建完成后,运行时,会自动创建一个空白的文档,下面可以将这个操作忽略。

// 在App类的实现函数Initinstance()函数中有这么一个操作:

//
分析标准 shell 命令、DDE、打开文件操作的命令行 CCommandLineInfo cmdInfo; if(cmdInfo.m_strFileName == _T("")) cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; // 阻止框架启动默认打开新的文档视图 ParseCommandLine(cmdInfo);
// 需要将cmdinfo的m_nShellCommand的标记改为FileNothing,表示在程序启动时,不会创建新的空白文档。

一个空的MDI项目只有一个文档,那就是向导产生的CDocument子类和CView子类,并且将这个文档注册到了程序中。

可以在Initinstance函数中有这么一段代码。

// 注册应用程序的文档模板。  文档模板
// 将用作文档、框架窗口和视图之间的连接
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_MFCMdiApplicationTYPE,
    RUNTIME_CLASS(CMFCMdiApplicationDoc),
    RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
    RUNTIME_CLASS(CMFCMdiApplicationView));    
if (!pDocTemplate)
    return FALSE;
AddDocTemplate(pDocTemplate);

这段代码就是注册了一个文档结构,那么如果需要多文档类型,那么需要再次注册不同的文档结构。

准备:

1、需要一个基于CMDIChildWnd的子类,用于管理新的文档结构。

2、需要一个基于CDocument的子类,用于保存数据。

3、需要一个基于CView的子类,用于显示数据。

class MyFrame : public CMDIChildWnd       // 细节忽略

class MyDoc : public CDocument          // 细节忽略

class MyView : public CFormView       // 细节忽略,CFormView继承的CView类,所以符合要求。

当实现了这三个类之后,需要把他注册到程序中。

// 这是向导生成的代码
//
注册应用程序的文档模板。 文档模板 // 将用作文档、框架窗口和视图之间的连接 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_MFCMdiApplicationTYPE, RUNTIME_CLASS(CMFCMdiApplicationDoc), RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架 RUNTIME_CLASS(CMFCMdiApplicationView)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate);
// 这里是新加的文档框架。 pDocTemplate
= new CMultiDocTemplate(IDR_MYFRAME, // 注意这里的资源,这里的资源包含了文档的标题,文档的类型等。 RUNTIME_CLASS(MyDoc), RUNTIME_CLASS(MyFrame), // 自定义 MDI 子框架 RUNTIME_CLASS(MyView)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate);

当AddDocTemplate函数注册两个及以上的时候,新建将会向用户询问要创建的文档类型。

运行项目,显示新建小窗口,选择类型,创建新文档。

也可以不使用新建命令来执行默认操作。那么当使用自定义的消息来打开文档时。可以执行以下操作:

// 该函数通过响应一个消息,来打开一个文档。前提是你已经注册了。
void MyView::OnCreateDefView()
{
    // TODO: 在此添加控件通知处理程序代码
    POSITION p = theApp.GetFirstDocTemplatePosition();
    while (p != NULL) {
        CDocTemplate* tmp = theApp.GetNextDocTemplate(p);
        CString str;
        tmp->GetDocString(str, CDocTemplate::fileNewName);
        if (str == _T("Default")) {
            tmp->OpenDocumentFile(NULL);
        }
    }
}

对于新建的文档窗口,他的外层受CMDIChildWnd框架管理,所以调整他的大小,都是在子框架类中处理。

那么,对于没有注册的文档类。需要自定义打开方式:

// MyView是我创建的基于CFormView的类
// child 是CChildFrame类(CMdiFrameWnd子类)(框架自带的子框架类),我在CMainFrame的h文件中创建了一个指针。并在构造函数中new的

// 以下代码在你需要的消息处理函数中运行,Initinstance或者OnCreate等。
CCreateContext con; con.m_pCurrentDoc
= 0; con.m_pNewViewClass = RUNTIME_CLASS(MyView); // 第一个参数是要使用的文档资源图标,我这里嫌麻烦直接使用了自带的。 child->LoadFrame(IDR_MFCApplication1TYPE, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, this); child->CreateView(&con); child->ShowWindow(SW_SHOW); // 这里可以在任何菜单处理命令中随时显示

运行程序后,就可以显示自定义的窗口了。

posted @ 2024-02-26 12:18  饼干`  阅读(29)  评论(0编辑  收藏  举报