1、 第 6 章 框架窗口、文档和视图尽管窗口、文档和视图是 MFC 的基础,但可能也是最不容易理解的部分,因为其概念比传统编程所需要的 Windows 函数更强一些,因此,须在本章做进一步详细讨论框架窗口、文档和视图的方法和技巧。6.1 框架窗口分两类:一是应用程序主窗口,另一类是文档窗口。6.1.1 主窗口和文档窗口主窗口(或称主框架窗口)是应用程序直接放在桌面(DeskTop)上的那个窗口,每个应用程序只能有一个窗口,主窗口的标题栏上往往显示应用程序的名称。主窗口类的源文件名是 MainFrm.h 和 MainFrm.cpp,其类名是 CMainFrame。单文档 SDI 程序主窗口类是从
2、CFrameWnd 派生来的。多文档 MDI 程序主窗口类是从 CMDIFrameWnd 派生的。如果应用程序中还有工具栏(CToolBar)状态栏( CStatusBar) ,那么在CMainFrame 类还含有表示工具栏和状态栏的成员变量 m_wndToolBar 和m_wndStatusBar,并在 CMainFrame 的 OnCreate 函数中进行初始化。文档窗口对于 SDI 程序来说,它和主窗口是一致的,即主窗口就是文档窗口;对于 MDI 程序,文档窗口是主窗口的子窗口。见书 244 页图 6.1 所示。文档窗口一般都有相应的可见边框,他的客户区(初了窗口标题栏、边框外的区域)是
3、由相应的视图来构成的,可以说视图是文档窗口内的子窗口。文档窗口时刻跟踪当前处于活动状态的视图的变化,并将用户或系统产生的命令消息传递给当前活动视图。而主窗口负责管理各个用户交互对象(包括菜单、工具栏、状态栏以及加速键)并根据用户操作相应地创建或更新文档窗口及其视图。在 MDI 应用程序中,MFC AppWizard 创建的文档子窗口类的源代码文件是 ChildFrm.h 和ChildFrm.cpp,其类名是 CChildFrame,它是从 CMDIChildWnd 派生的。6.1.2 窗口风格的设置窗口的风格决定了窗口的外观及功能,用户通过风格的设置增加或减少窗口中所包含的功能,这些功能一般都
4、是由系统内部定义的,不需要用户去编程实现。窗口风格可以通过 MFC AppWizard 来设置,也可以在主窗口或文档窗口类的PreCreateWindow 函数中修改 CREATESTRUCT 结构,或是可以调用 CWnd 类的成员函数 ModifyStyle 和 ModifyStyleEx 来更改。1、窗口风格通常以 WS_为前缀和扩展以 WS_EX_为前缀两种形式;这两种形式的窗口风格可在函数 CWnd:Create(只能指定窗口的一般风格)或 CWnd:CreateEx(可同时支持以上两种风格) ,对于控件和对话框这样的窗口来说,它们的窗口风格可直接通过其属性对话框来设置。常见的一般窗口
5、风格如下所示:(书 245 页表 6.1)WS_BORDER 窗口含有边框WS_CAPTION 窗口含有标题栏(它意味着还具有 WS_BORDER 风格)但它不能和 WS_DLGFRAME 组合WS_CHILD 创建子窗口,它不能和 WS_POPUP 组合WS_CLIPCHILDREN 在父窗口范围内裁剪子窗口,它通常在父窗口创建时指定WS_CLIPSIBLINGS 裁剪相邻子窗口,也就是说,具有此风格的子窗口和其他子窗口重叠的部分被裁剪,它只和 WS_CHILD 组合WS_DISABLED 窗口最初时是禁用的WS_DLGFRAME 窗口含有双边框,但没有标题WS_GROUP 此风格被控件组中
6、第 1 个控件窗口指定。用户可在控件组的第 1 个和最后 1 个控件中用方向键来选择WS_HSCROLL 窗口最初时处于最大化WS_MAXIMIZEBOX 在窗口的标题栏上含有”最大化” 按钮WS_MINIMIZE 窗口最初处于最小化,他只和 WS_OVERLAPPED 组和WS_MINIMIZEBOX 在窗口的标题栏上含有” 最小化”按钮WS_OVERLAPPED 创建覆盖窗口,一个覆盖窗口通常有一个标题和边框WS_OVERLAPPEDWINDOW 创建一含有WS_OVERLAPPED、WS_CAPTION、WS_SYSMENU、WS_THICKFRAME 、WS_MINIMIZEBOX 和
7、 WS_MAXIMIZEBOX风格的覆盖窗口WS_POPUP 创建一弹出窗口,它不能和 WS_CHILD 组合,只能用CreateWx 函数指定WS_POPUPWINDOW 创建一含有 WS_BORDER、WS_POPUP 和WS_SYSMENU 风格的弹出窗口。当 WS_CAPTION 和WS_POPUPWINDOW风格组合时才能使系统菜单可见。WS_SYSMENU 窗口的标题栏上含有系统菜单框,它仅用于含有标题的窗口WS_TABSTOP 用户可以用于 TAB 键 选择控件组中的下一个控件WS_THICKFRAME 窗口含有边框,并可调整窗口的大小WS_VISIBLE 窗口最初是可见的WS_
8、VSCROLL 窗口含有垂直滚动条除了这些风格外,框架窗口还有以下 3 个自己的风格。他们都可以在PreCreateWindow 重载函数中指定。(1)FWS_ADDTOTITLE 风格:指定一个文档名添加到框架窗口标题中,如书244 页图 6.1 的“Ex_MDI-Ex_MDI1”的 Ex_MDI1 是文档名。若单文档应用程序,默认的文档名是” 无标题 ”。(2)FWS_PREFIXTITLE 风格:使得框架窗口标题中的文档名显示在应用程序名之前。例如,若未指定该风格时的窗口标题为”Ex_MDI_Ex_MDI1”, 当指定该风格后就变成了” Ex_MDI1_Ex_MDI”。(3)FWS_SN
9、APTOBARS 风格:用于调整窗口的大小,使它刚好包含了框架窗口中的控制栏(如工具栏)2、用 MFC AppWizard 设置MFC AppWizard 有一个 Advanced(高级)按钮(在创建单或多文档程序时的第 4 步中) ,允许用户指定有关 SDI 和 MDI 框架窗口的属性。见书 246 页图6.2 所示为”Advanced Options”对话框的 Window Styles 页面,其中的含义如下:(246 页)(但在该对话框中,用户只能设定少数几种窗口风格)Use split window(应用拆分窗口) 选中时,将程序的文档窗口创建成”切分”*( 或称拆分)窗口Thick
10、frame(厚框) 选中时,设置窗口风格 WS_THICKFRAMEMinimize box(最小化框符 ) 选中时,设置窗口风格 WS_MINIMIZEBOXMaximize box(最大化框符) 选中时,设置窗口风格 WS_MAXIMIZEBOXSystem menu(系统菜单) 选中时,设置窗口风格 WS_SYSMENUMinimized(最小化) 选中时,设置窗口风格 WS_MINIMIZEMaximized(最大化 ) 选中时,设置窗口风格 WS_MAXIMIZE3、修改 CREATESTRUCT 结构在窗口创建之前,系统自动调用 PreCreateWindow 虚函数。在 MFC
11、AppWizard创建 SDI/MDI 应用程序结构时,MFC 已为主窗口或文档窗口类自动重载了该虚函数。我们可以在此函数中通过修改 CREATESTRUCT 结构来设置窗口的绝大多数风格。例:在 SDI 程序中,框架窗口默认的风格是 WS_OVERLAPPEDWINDOW 和FWS_ADDTOTITLE 的组合,更改其风格。(1)建一个单文档的应用程序(2)在主框架程序 MainFrm.cpp 中找到 PreCreateWindow 虚函数,并加代码:BOOL CMainFrame:PreCreateWindow(CREATESTRUCT/新窗口不带有最大化按钮cs.cy=:GetSyste
12、mMetrics(SM_CYSCREEN)/3;cs.cx=:GetSystemMetrics(SM_CYSCREEN)/3;/将窗口大小设置为 1/3 屏幕大/小,并居中。cs.y=(cs.cy*3)-cs.cy)/2;cs.x=(cs.cx*3)-cs.cx)/2;/调用基类的 PreCreateWindow(cs)函数return CFrameWnd:PreCreateWindow(cs);/ if( !CFrameWnd:PreCreateWindow(cs) )/ return FALSE;/ TODO: Modify the Window class or styles here
13、by modifying/ the CREATESTRUCT cs/ return TRUE;(3)编译运行,见出现的窗口是原来的 1/3。(4)建一个多文档 MDI 应用程序(先运行一下试一试窗口最大化按钮)(5)在子文档窗口 ChildFrm 程序中找到 PreCreateWindow 虚函数,并加代码:(创建不含有最大化 按钮的子窗口)BOOL CChildFrame:PreCreateWindow(CREATESTRUCT/创建不含有最大化按钮的子窗口return CFrameWnd:PreCreateWindow(cs);/ if( !CMDIChildWnd:PreCreateWi
14、ndow(cs) )/ return FALSE;/ return TRUE;结果是:不含有最大化 按钮的子窗口代码中,前面有“:”作用域符号的函数是指全局函数。代码“cs.style ”中的“”是按位取“反”运算符,它将 WS_MAXIMIZEBOX 的值按位取反后,再和 cs.style 值按位“与” ,其结果是将 cs.style 值中的 WS_MAXIMIZEBOX 标志位清零。4、使用 ModifyStyle 和 ModifyStyleExCWnd 类中的成员函数 ModifyStyle 和 ModifyStyleEx 也可用来更改窗口的风格,其中 ModifyStyleEx 还可更
15、改窗口的扩展风格。这两个函数具有相同的参数:BOOL ModifyXXXX(DWORD dwRemove,DWORD dwAdd,UINT nFlags=0);参数:dwRemove 用来指定需要删除的风格dwAdd 用来指定需要增加的风格nFlags 表示 SetWindowPos 的标志,0(默认)表示更改风格的同时不调用 SetWindowPos 函数由于框架窗口在创建时不能直接设定其扩展风格,因此只能通过调用ModifyStyle 函数来进行。例:在多文档(MDI)的子文档窗口增加水平和垂直滚动条(书 247 页例,248页图 6.3)(1)用 MFC AppWizard 创建一个多文
16、档应用程序(或用上个多文档应用程序) ,名为:“多文档”(2)用 ClassWizard 为子文档窗口类 CChildFrame 添加 OnCreateClient 处理消息:ViewClassWizardCChildFrameOnCreateClientAdd FunctionEdit Code并加如下代码:BOOL CChildFrame:OnCreateClient(LPCREATESTRUCT lpcs,,CCreateContext* pContext) / TODO: Add your specialized code here and/or call the base class
17、ModifyStyle(0,WS_VSCROLL,0);/垂直滚动轴ModifyStyle(0,WS_HSCROLL,0);/水平滚动轴return CMDIChildWnd:OnCreateClient(lpcs, pContext);(3)编译并运行(书上只有一个滚动轴)6.1.3 窗口状态的改变MFC AppWizard 为每个窗口设置了相应的大小和位置,但总有的默认窗口不另人满意,这时就需要进行适当的调整。1、用 ShowWindow 改变窗口的显示状态当应用程序运行时,Windows 会自动调用应用程序框架内部的 WinMain 函数,并自动查找该应用程序类的全局变量 theApp,
18、然后自动调用用户应用程序类的虚函数 InitInstance,该函数会进一步调用相应的函数来完成主窗口的构造和显示工作,如一个单文档应用程序的应用程序文件中的程序名.cpp 中的 InitInstance()函数中的代码:m_pMainWnd-ShowWindow(SW_SHOW);m_pMainWnd-UpdateWindow();参数:SW_SHOW 是用当前的大小和位置激活并显示窗口。m_pMainWnd 是主框架窗口指针变量, ShowWindow 是 CWnd 类的成员函数,用于按指定的参数显示窗口,该参数的值如下:SW_HIDE 隐藏此窗口并将激活状态移交给其他窗口SW_MINIM
19、IZE 将窗口最小化并激活系统中的顶层窗口SW_RESTORE 激活并显示窗口。若窗口是最小或最大状态时,则恢复到原来的大小和位置SW_SHOW 用当前的大小和位置激活并显示窗口SW_SHOWMAXIMIZED 激活窗口并使之最大化SW_SHOWMINIMIZED 激活窗口并使之最小化SW_SHOWMINNOACTIVE 窗口显示成为一个图标并保留其激活状态(即原来是激活的,仍然是激活)SW_SHOWNA 用当前状态显示窗口SW_SHOWNOACTIVATE 用最近的大小和位置状态显示窗口并保留其激活状态SW_SHOWNORMAL 激活并显示窗口 通过指定 ShowWindow 函数的参数值可
20、以改变窗口显示状态,例如:将窗口的初始状态设置为” 最小化” ,可以这样写:m_pMainWnd-ShowWindow(SW_SHOWMINIMIZED);m_pMainWnd-UpdateWindow(); 由于用户应用程序类继承了基类 CWinApp 的特性,因此也可在用户应用程序类CWinApp 中使用公有型(public)成员变量 m_nCmdShow,通过对其进行赋值,同样能达到效果。例如:在上个“多文档”项目的应用程序的 InitInstance()函数中这样写:m_nCmdShow=SW_SHOWMAXIMIZED;/激活窗口并使之最大化,书是最小pMainFrame-ShowW
21、indow(m_nCmdShow);pMainFrame-UpdateWindow();return TRUE;2、用 SetWindowPos 或 MoveWindow 改变窗口的大小和位置CWnd 中的 SetWindowPos 是一个非常有用的函数,它不仅可以改变窗口的大小、位置,而且还可以改变所有窗口在堆栈排列的次序(Z 次序) ,这个次序是根据它们在屏幕出现的先后来确定的。BOOL SetWindowPos(const CWnd *pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);参数:pWndInsertAfter 表示窗
22、口对象指针,它可以预定义下列窗口对象的地址:wndBottom 将窗口放置在 Z 次序中的底层wndTop 将窗口放置在 Z 次序中的顶层wndTopMost 设置最顶层窗口wndNoTopMost 将窗口放置在所有最顶层的后面,若此窗口不是最顶窗口,则此标志无效。x 和 y 表示窗口新的左上角坐标,cx 和 cy 分别表示窗口的宽度和高度,nFlags 表示窗口新的大小和位置方式,如下说明(书 250 页表 6.4)常用 nFlags 值及其含义:SWP_HIDEWINDOW 隐藏窗口SWP_NOACTIVATE 不激活窗口。如该标志没有被指定,则依赖 pWndInsertAfter 参数S
23、WP_NOMOVE 不改变当前的窗口位置(忽略 x 和 y 参数)SWP_NOOWNERZORDER 不改变父窗口的 Z 次序SWP_NOREDRAW 不重新绘制窗口SWP_NOSIZE 不改变当前的窗口大小(忽略 cx 和 cy 参数)SWP_NOZORDER 不改变当前的窗口 Z 次序(忽略 pWndInsertAfter 参数)SWP_SHOWWINDOW 显示窗口函数 CWnd:MoveWindow 也可用来改变窗口的大小和位置,与 SetWindowPos 函数不同的是,用户必须在 MoveWindow 函数中指定窗口的大小。void MoveWindow(int x,int y,i
24、nt nWidth,int nHeight,BOOL bRepaint=TRUE);void MoveWindow(LPCRECT lpRect,BOOL bRepaint=TRUE);参数:x,y 表示窗口新的左上角坐标nWidth,nHeight 表示窗口新的宽度和高度bRepaint 用于指定窗口是否重绘lpRect 表示窗口新的大小和位置例:用上面两个函数,把主窗口移到屏幕的(100,100)处。(1)建一个单文档的应用程序(2)打开:文件名.cpp 应用程序,找到 BOOL CMyApp:InitInstance()函数,并添下列代码:m_pMainWnd-SetWindowPos(
25、NULL,100,100,0,0,SWP_NOSIZE|SWP_NOZORDER);/不改变当前的窗口大小和窗口 Z 次序,CRect rcWindow; /见上面说明(书 250 页表 6.4)m_pMainWnd-GetWindowRect(rcWindow);m_pMainWnd-MoveWindow(100,100,rcWindow.Width(),rcWindow.Height(),TRUE);/改变窗口位置/AfxGetMainWnd()-CenterWindow();/将主框架窗口居中./AfxGetMainWnd()-CenterWindow(CWnd:GetDesktopWi
26、ndow();/将窗口置于屏幕中央/return TRUE; 当然,改变窗口的大小和位置的 CWnd 成员函数还不止以上两个,例如:CenterWindow(CWND:GetDesktopWindow() )函数是使窗口居于父窗口(屏幕)中央。AfxGetMainWnd()-CenterWindow();/将主框架窗口居中。见上面已加上的两个函数。6. 2 文档模板用 MFC AppWizard 创建的单文档(SDI)或多文档( MDI)应用程序均包含应用程序类、文档类、视图类和框架窗口类,这些类是通过文档模板有机地联系在一起的。6.2.1 文档模板类文档应用程序框架结构是在程序运行一开始构造
27、的。1、在单文档应用程序的应用程序类 InitInstance()函数中,可以看到这样的代码:BOOL CMyApp:InitInstance()CSingleDocTemplate *pDocTemplate;pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME, /资源 IDRUNTIME_CLASS(CMyDoc), /(以中文名字命名的项目名的项目)文档类RUNTIME_CLASS(CMainFrame),/ 主框架窗口类RUNTIME_CLASS(CMyView) /(以中文名字命名的项目名的项目)视图类);AddDocTemplat
28、e(pDocTemplate);.return TRUE; 代码中:pDocTemplate 是类 CSingleDocTemplate 的指针对象。CSingleDocTemplate 是一个单文档模板类,他的构造函数中有 4 个参数,分别表示菜单和加速键等的资源 ID 号以及 3 个由宏RUNTIME_CLASS指定的运行时类对象。AddDocTemplate 是类 CWinApp 的一个成员函数,当调用了该函数后,就建立了应用程序类、文档类、视图类和主框架类之间的相互联系。2、在多文档应用程序的应用程序类 InitInstance()函数中,同样可以看到这样的代码:BOOL CMyApp
29、:InitInstance() CMultiDocTemplate* pDocTemplate;pDocTemplate = new CMultiDocTemplate(IDR_MYTYPE, /(以中文名字命名的项目名的项目)资源 ID 号RUNTIME_CLASS(CMyDoc),/(以中文名字命名的项目名的项目)文档类RUNTIME_CLASS(CChildFrame),/ MDI 文档窗口类RUNTIME_CLASS(CMyView)/(以中文名字命名的项目名的项目)视图类);AddDocTemplate(pDocTemplate);/ create main MDI Frame wi
30、ndow 创建主框架窗口CMainFrame* pMainFrame = new CMainFrame;if (!pMainFrame-LoadFrame(IDR_MAINFRAME)return FALSE;m_pMainWnd = pMainFrame;Return TRUE;由于多文档模板是用于建立资源、文档类、视图类和子框架窗口(文档窗口)类之间的联系的,因而多文档的主框架窗口需要额外的代码来创建。代码中:LoadFrame()是 CFrameWnd 类成员函数,用于加载与主框架窗口相关的菜单、加速键、图标等资源。说明:多文档主框架窗口的创建应在多文档模板创建后进行,以便 MFC 程序
31、框架将多文档模板和多文档主框架窗口建立联系。应用程序类对象在模板被创建之前就已经存在,但此时文档、视图及框架对象还没有被创建。程序运行后,程序框架会动态地创建这些对象。这一动态创建的过程包含了对 C+语言的非常复杂的运用。通过在用户文档类、视图类以及主框架类的定义(.h)及实现(.cpp)过程中使用 DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 宏,MFC 库可以动态地创建相应的类对象。这种称为运行时类的动态创建机制,简化了程序员编程工作,拓展了“类”的功能,是 MFC 程序框架结构的重要特性。6.2.2 文档模板字串资源 在 MFC AppWizard 创建
32、的应用程序资源中,许多资源标识符都是IDR_MAINFRAME意味着这些具有同名标识的资源将被框架自动加载到应用程序中。其中 String Table(字符串) 资源列表中也有一个 IDR_MAINFRAME 项,他是用于标识文档类型、标题等内容的,称为“文档模板字串资源” 。其内容如下(以单文档“模板”为例)模板nnMynnnMy.DocumentnMy Document可以看出,IDR_MAINFRAME 所标识的字符串被分成了一些以“n ”结尾的子串,这些子串共有 7 段,每段都有特定的用途,如:(252 页表 6.5)文档模板字符串的含义:IDR_MAINFRAME 的子串 串号 用途
33、模板n 0 应用程序窗口标题即窗口标题栏 :无标题-模板 n 1 文档根名。对多文档应用程序来说,若在文档窗口标题上显示“Sheet1” ,则其中的 Sheet就是文档根名,若该子串为空,则文档名为默认的“无标题”Myn 2 新建文档的类型名。若有多个文档类型,则这个名称将出现在“新建”对话框中n 3 通用对话框的文件过滤器正文n 4 通用对话框的文件扩展名My.Documentn 5 在注册表中登记的文档类型标识My Document 6 在注册表中登记的文档类型名称但对于 MDI(多文档)来说,上述的字串分别由 IDR_MAINFRAME 和IDR_MYTYPE(项目名为:中文名:“字串资
34、源“)2 项组成;其中,IDR_MAINFRAME 表示窗口标题,而 IDR_MYTYPE 表示后 6 项内容。它们的内容如下:IDR_MAINFRAME: My(中文项目名)IDR_MYTYPE: nMynnnMy.DocumentnMy Document实际上,文档模板字串资源内容既可直接通过字串资源编辑器进行修改,也可以在文档应用程序中创建向导的第 4 步中,通过“Advanced Options”对话框中的“Document Template String”页面来指定,如书 235 页图 6.4 所示(名字是Ex_SDI) 。图中的数字表示该项的含义与上表中对应串号的含义相同。6.2.
35、3 使用多个文档类型在 MFC AppWizard 创建的应用程序中,通常只有一种文档类型。但有时,用户也需要另一种文档类型。例如 Visual C+6.0 本身既要处理文本文件,也要处理MFC 资源,至少要有 2 种文档类型。多种文档类型的应用程序中一般有多个文档模板、多个文档类以及与之紧密相联的多个视图类。当用户选择“文件”菜单的“新建”命令时,应用框架将弹出含有文档类型列表的对话框,允许用户自己选择所需的文档类型。下面是实现在多文档应用应用程序中使用多种文档类型。例:使用多个文档(1)用 MFC AppWizard 创建一个多文档应用程序(Step1 第一步就单击Finish即可)(2)
36、 (3) “多个文档类型实例”(4)nPicturenMyDenmo 图片n 图片文件(*.bmp)n.bmpnMyDemo.DocumentnMy Document(5)在“字符串属性”对话框中将 ID 设为 IDR_OTHERTYPE=130,标题内容设为:nTxtnMyDemo 文本n 文本文件(*.txt,*.cpp,*.h)n.txt;*.cpp,*.hnMyDemo.Documentn MyDocument(6)COtherDoc(7)COtherDoc(8)pDocTemplate=new CMultiDocTemplate(IDR_OTHERTYPE,RUNTIME_CLASS
37、(COtherDoc),/指定新的文档类RUNTIME_CLASS(CChildFrame),RUNTIME_CLASS(COtherView);/指定新的视图类AddDocTemplate(pDocTemplate);(9) #include “OtherDoc.h“#include “OtherView.h“(10)运行结果见书说明:A、如果在该例程序中再添加图标和菜单资源,并使资源标识设为IDR_OTHERTYPE则当创建“MyDemo 文本”文档类型后,程序会自动使用新的图标和菜单资源。B、单文档应用程序也可以有多个文档类型,它的实现方法与多文档类似,也是通过添加文档模板来实现的,只不
38、过每次只能在文档窗口(视图)中显示一个文档。6.3 文档序列化用户处理的数据往往需要存盘作为永久备份。将文档类中的数据成员变量的值保存在磁盘文件中,或者将存储的文档文件中的数据读取到相应的成员变量中,这个过程称为序列化(Serialize) 。6.3.1 文档序列化过程在使用 MFC 程序结构进行文档序列化之前,我们先了解对文档不同操作的具体程序运行过程。1 创建空文档(256 页有说明)应用程序类的 InitInstance 函数在调用了 AddDocTemplate 函数之后,会通过 CWinApp:ProcessShellCommand 间接调用 CWinApp 的另一个非常有用的成员函
39、数 OnFileNew,并依次完成文档各个步骤的创建。.2)打开文档当 MFC AppWizard 创建应用程序时,它会自动将 “文件(File) ”选单中的“打开(Open ) ”命令(ID 号为 ID_FILE_OPEN)映射到 CWinApp 的OnFileOpen成员函数。这一结果可以从应用类(.cpp)的消息入口处得到验证:见书 257 页除了使用“文件(File) ”“打开(Open) ”选项外,用户也可以选择最近使用过的文件列表来打开相应的文档。在应用程序的运行过程中,系统会记录下4 个(默认)最近使用过的文件,并将文件名保存在 Windows 的注册表中。当每次启动应用程序时,
40、应用程序都会在“文件(File) ”选单中显示最近使用过的文件名称。需要说明的是:MFC 为我们重载了 Serialize 函数,不必使用 CFile 类就可以完成相应的文档操作。 (写磁盘和串口访问这样这样的任务)例:使用 Serialize 函数,读取文档中的数据(附加)(1)打开前面的“多文档”应用程序或重新建一个单或多文档应用程序。(2)加成员变量工作区 ClassView右键对准 CMyDoc单击Add Member Variable右键单击 出现对话框 Variable Type 处写:char Variable Name 处写:m_ch300在文档类中加了一个成员变量。(3)在文档类即多文档 Doc.cpp 中找到:void CMyDoc:Serialize(CArchiveim_chi;CString str;str.Format(_T(“%s“),m_ch);AfxMessageBox(str);这样,当我们通过选单的“打开(Open) ”成功打开(用*.*)一个文件时,