7.2文档及其序列化 7.21单文档和多文档 个多文档应用程序的示例过程 (1)用 MFC AppWizard创建一个多文档应用程序项目 EX Mdi。由于向导默认创建的就 是这种程序类型,因此只要在向导的Sep1对话框中单击[Fnsh]按钮即可创建一个 默认的多文档应用程序 2)打开 CEx_ MdiApp: nitInstance可看出与默认的单文档应用程序不同的代码是: BOOL CEX_ MdiApp: Initinstanceo CMultiDocTemplate* pDocTemplate pDocTemplate new CMultiDocTemplate( IDR EX MDITYPE RUNTIME_ CLASS(CEX_ Mdidoc) RUNTIME CLASS( CChildframe),∥/MDI文档子窗口 RUNTIME_ CLASS(CEX_ Mdiview)) AddDocTemplate(pDocTemplate) ∥/创建MDI主框架窗口 CMainFrame pAin Frame new MAin Frame if (pMain Frame->Load Frame(IDR_MAINFRAME)) return false m-pMainWnd= pMainFrame
7.2文档及其序列化 7.2.1单文档和多文档 一个多文档应用程序的示例过程: (1)用MFC AppWizard创建一个多文档应用程序项目Ex_Mdi。由于向导默认创建的就 是这种程序类型,因此只要在向导的Step 1对话框中单击[Finish]按钮即可创建一个 默认的多文档应用程序。 (2)打开CEx_MdiApp::InitInstance可看出与默认的单文档应用程序不同的代码是: BOOL CEx_MdiApp::InitInstance() { … CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_EX_MDITYPE, RUNTIME_CLASS(CEx_MdiDoc), RUNTIME_CLASS(CChildFrame), // MDI文档子窗口 RUNTIME_CLASS(CEx_MdiView)); AddDocTemplate(pDocTemplate); // 创建MDI主框架窗口 CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; … }
7.2文档及其序列化 (3)用 ClassWizard为该项目添加一个 CDocument派生类 CAnotherdoc,并在 CEx Mdi- Ap pp: InitInstance增加下列代码 BOOL CEX_ MdiApp: Initinstanceo CMultiDocTemplate* pDocTemplate DocTemplate new CMultiDocTemplate(IDR_EX_MDITYPE, RUNTIME_CLASS(CEX_ MdiDoc) RUNTIME CLASS( CHild frame),/MDI文档子窗口 RUNTIME_CLASS(CEX_Mdiview)) AddDocTemplate(pDocTemplate) CMultiDocTemplate* pAnther pAnother= new CMultiDocTemplate(IDR_EX MDITYPE, RUNTIME_CLASS(CAnotherDoc) RUNTIME CLASSI( CChildframe),∥/MDI文档子窗口 RUNTIME_ CLASS(CEX Mdiview)) AddDocTemplate(aNother) ∥/创建MDI主框架窗口 CMainFrame'* pAin Frame new CMain Frame: if (pAin Frame->LoadFrame(IDR_MAINFRAME)) return false. m_pMainWnd= pMainFrame
7.2文档及其序列化 (3)用ClassWizard为该项目添加一个CDocument派生类CAnotherDoc,并在CEx_MdiApp::InitInstance增加下列代码: BOOL CEx_MdiApp::InitInstance() { … CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_EX_MDITYPE, RUNTIME_CLASS(CEx_MdiDoc), RUNTIME_CLASS(CChildFrame), // MDI文档子窗口 RUNTIME_CLASS(CEx_MdiView)); AddDocTemplate(pDocTemplate); CMultiDocTemplate* pAnother; pAnother = new CMultiDocTemplate(IDR_EX_MDITYPE, RUNTIME_CLASS(CAnotherDoc), RUNTIME_CLASS(CChildFrame), // MDI文档子窗口 RUNTIME_CLASS(CEx_MdiView)); AddDocTemplate(pAnother); // 创建MDI主框架窗口 CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; … }
7.2文档及其序列化 (4)在 Ex_Mdi. cpp文件的开始处,添加包含 CAnotherDoc类的头文件 #include"AnotherDoc h (5)编译并运行后,如图,从中选择一个文档类型。任何时候,选择 Ex Mdi程序的 “文件”菜单→“新建”命令或单击“新建”工具按钮都将弹出此对话框 选定第二个文档类型后,单击[确定]。这时程序出现一个断言错误,这是因为在视图 类中有一个 GetDocumen函数,它的代码如下 CEx_MdiDoc* CEx_Mdiview: GetDocumento / non-debug version is inline ASSErT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEX_MdiDoc)) return(CEx_ MdiDoc )m_ pDocument; } 创建的文档类型是 CAnotherdoc时,由于两种类型的文档共用一个视图,调用的 GetDocument函数是同一个函数,因此断言不成立,程序不能正常运行。 (6)用 Classwizard为该项目添加一个 CView类的派生类 ANother view,并将 InitInstance第二模板 aNother中的 CEx Mdiview改成 ANother view,然后在该源文 件前面添加 ANother view的头文件 Another View h (7)再次运行,上述问题得到解决。但是,图74的文档“新建”对话框中显示的文档 类型名称应该怎么修改呢?这时就需要使用文档的字串资源。 新建 新建a 取消 图74文档“新建”对话框
7.2文档及其序列化 (4)在Ex_Mdi.cpp文件的开始处,添加包含CAnotherDoc类的头文件: #include "AnotherDoc.h" (5)编译并运行后,如图,从中选择一个文档类型。任何时候,选择Ex_Mdi程序的 “文件”菜单→“新建”命令或单击“新建”工具按钮都将弹出此对话框。 选定第二个文档类型后,单击[确定]。这时程序出现一个断言错误,这是因为在视图 类中有一个GetDocument函数,它的代码如下: CEx_MdiDoc* CEx_MdiView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEx_MdiDoc))); return (CEx_MdiDoc*)m_pDocument; } 创建的文档类型是CAnotherDoc时,由于两种类型的文档共用一个视图,调用的 GetDocument函数是同一个函数,因此断言不成立,程序不能正常运行。 (6)用ClassWizard为该项目添加一个CView类的派生类CAnotherView,并将 InitInstance第二模板pAnother中的CEx_MdiView改成CAnotherView,然后在该源文 件前面添加CAnotherView的头文件AnotherView.h。 (7)再次运行,上述问题得到解决。但是,图7.4的文档“新建”对话框中显示的文档 类型名称应该怎么修改呢?这时就需要使用文档的字串资源。 图7.4 文档“新建”对话框
7.2文档及其序列化 722文档的字串资源 通过对文档的字串资源修改可以改变文档窗口标题、文档类型以及通用文 件对话框中的某些内容。例如下面的示例过程: (1)打开前面的多文档应用程序项目 Ex Mdi。 (2)打开 String Table,将 IDR EX MDITYPE字串资源复制,复制后的ID为 IDR ANOTHERTYPE,修改这两个字串资源,结果如下表所示。 如果 IDR ANOTHERTYPE的值不等于130,可在其属性对话框中直接给标识 赋值,如图。 (3)将 InitInstance第二模板 aNother中的资源号DR_ EX MDITYPE改成 IDR ANOTHERTYPE 字符串强源ID 值标题 IDR EX MDITYPE129 unPicturelnEx M图片in图片文件 (* bmp)un.bmplnExMdi Document\nEx Mi Document IDR ANOTHERTYPE 130 TxtnEx N文本mn文本文件(*tt*cp * h)n tct; * cpp*h n Ex Mdi Document nEx Mdi Document string w? General I ID: IDR_ANOTHERTYPE=130 Caption:n T xtinEx M和m文本文件∵P:时 An. txt,*. cpp h'inExMdi Document\ Ex Mdi Document 图75指定标识值
7.2文档及其序列化 7.2.2文档的字串资源 通过对文档的字串资源修改可以改变文档窗口标题、文档类型以及通用文 件对话框中的某些内容。例如下面的示例过程: (1)打开前面的多文档应用程序项目Ex_Mdi。 (2)打开String Table,将IDR_EX_MDITYPE字串资源复制,复制后的ID为 IDR_ANOTHERTYPE,修改这两个字串资源,结果如下表所示。 如果IDR_ANOTHERTYPE的值不等于130,可在其属性对话框中直接给标识 赋值,如图。 (3)将InitInstance第二模板pAnother中的资源号IDR_EX_MDITYPE改成 IDR_ANOTHERTYPE。 图7.5 指定标识值
7.2文档及其序列化 (4)重新编译并运行,如图。测试后还发现“打开”或“保存”对话框中的 “文件类型”框中显示出文档字串资源定义的类型名,如图。 文档资源字串的内容也可在文档应用程序创建时的 Advanced Options对话 框中指定,如图,图中数字表示该项的含义与表中对应串号的含义相同。 新建 dvanced Options Document Template Strings window Styles I Non-localized strings File extension: File type ID: 图76“新建”对话框 ExMdi. Document calized strings Language Main frame caption 中文中国 ame Filter name: 围口B +图即 Ex Mdi File new name [short File type name [long ame Ex Mdi document 件谷① 打开。 其型①)[本并你· Close 图78 Advanced Options对话框 图77 Ex Mdi运行结果
7.2文档及其序列化 (4)重新编译并运行,如图。测试后还发现“打开”或“保存”对话框中的 “文件类型”框中显示出文档字串资源定义的类型名,如图。 文档资源字串的内容也可在文档应用程序创建时的Advanced Options对话 框中指定,如图,图中数字表示该项的含义与表中对应串号的含义相同。 图7.7 Ex_Mdi运行结果 图7.8 Advanced Options对话框 0 4 5 2 6 1 3 图7.6 “新建”对话框