1、VC 菜单命令详解 (文件打开、保存与关闭)第一部分:五个命令 ID: 处理函数 ID_FILE_NEW CWinApp:OnFileNew ID_FILE_OPEN CWinApp:OnFileOpen ID_FILE_SAVE CDocument:OnFileSave ID_FILE_SAVEAS CDocument:OnFileSaveAs ID_FILE_CLOSE CDocument:OnFileClose 1.ID_FILE_NEW CWinApp:OnFileNew 调用 CDocManager:OnFileNew。 | CDocManager:OnFileNew 判断文档模板是
2、否多于一个,是则显示文档类型对话框(AFX_IDD_NEWTYPEDLG) 让用户选择要创建的文档类型。然后调用 CDocTemplate:OpenDocumentFile(NULL)。 | CDocTemplate:OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMake_Visible=TRUE)对于 SDI 和 MDI 的 处理不一样。 对于 SDI,1,若已有文档打开,对其重新初始化,调用 CDocument:SaveModified()保存当前文档;若没 有文档存在,则调用 CreateNewDocument()创建文档对象,再调用Create
3、NewFrame(pDoucment,NULL)创建 文档的框架窗口。2,若 lpszPathName 为 NULL,则调用 CDocument:OnNewDocument()处理新文档,用 pDocument-SetPathName(lpszPathName)设置文档的路径。3,判断当前线程主框架窗口是否存在,不存 在则将 1 中创建的新框架作为主框架。4,调用 InitialUpdateFrame 显示框架窗口。 对于 MDI,与 SDI 基本相同,但是没有第 3 步。 | CDocument:OnNewDocument()首先调用 DeleteContents()删除原文档内容,使用m_
4、strPathName.Empty() 清除当前文档路径,SetModifiedFlag(FALSE)。 2.ID_FILE_OPEN CWinApp:OnFileOpen 调用 CDocManager:OnFileOpen。 | CDocManager:OnFileOpen 首先显示文件打开对话框(AFX_IDS_OPENFILE),然后调用CWinApp: OpenDocumentFile(FileName)。 | CWinApp:OpenDocumentFile(FileName)调用 CDocManager:OpenDocumentFile。 | CDocManager:OpenDoc
5、umentFile(LPCTSTR lpszFileName)遍历文档模板,对每个模板用 MatchDocType(szPath,pOpenDocument)匹配文档类型。匹配时主要根据文件扩展名判断。若文件已经在 某个文档中打开,则激活文档的第一个视图,否则用匹配的文档模板 pBestTemplate-OpenDocumentFile (szPath)。 | CDocTemplate:OpenDocumentFile 调用 CDocument:OnOpenDocument 打开文件。 | CDocument:OnOpenDocument 打开文件,用 DeleteContents 删除现有文
6、档内容,创建文件对应的 CArchive 对象 loadArchive,Serialize(loadArchive)读文件内容,SetModifiedFlage(FALSE)。 MDI: New Frame, New View? SDI: Update View? 3.ID_FILE_SAVE CDocument:OnFileSave 调用 CDocument:DoFileSave()。 | CDocument:OnFileSave 判断文件是否只读,是则 DoSave(NULL),否则DoSave(m_strPathName)。 | CDocument:DoSave(LPCTSTR lpsz
7、PathName,BOOL bReplace=TRUE)的流程为:1,判断lpszPathName 不空 则跳第二步,为空则获取文档的路径名,加上扩展符。bReplace 为 TRUE 则显示保存文件对话框(AFX_IDS_ SAVEFILE),否则显示拷贝保存对话框(AFX_IDS+SAVEFILECOPY) 。2,调用CDocument:OnSaveDocument 保 存文档。3,若 bReplace=TRUE 则 SetPathName(newName)覆盖当前路径名。 | CDocument:OnSaveDocument 打开文件,创建 CArchive 对象saveArchive,
8、Serialize(saveArchive) 读写 文件,SetModifiedFlag(FALSE)。 4.ID_FILE_SAVEAS CDocument:OnFileSave 调用 DoSave(NULL)。 5.ID_FILE_CLOSE CDocument:OnFileClose 调用 SaveModified()保存文件,再用 OnCloseDocument 处理文档关闭。 | CDocument:SaveModified()用 IsModified()判断是否修改,是则显示文件保存对话框(AFX_IDP_ASK_TO_ SAVE),若用户选择“是” ,则调用 DoFileSave
9、()保存文件。 | CDocument:OnCloseDocument()首先销毁文档框架,再用 DeleteContents()删除文档内容,若 m_ bAutoDelete 则 delete this。 第二部分:MDI 打开文件的过程 CWinApp:OnFileOpen() CDocManager:OnFileOpen() CDocManager:DoPromptFileName() CFileDialog:DoModal(); CWinApp:OpenDocumentFile() .选择文档模板; .调整视图和框架; CDocTemplate:OpenDocumentFile();
10、判断有无现存文档,是否需要保存 新建框架 判断文件是否存在,调用 CMyDoc:OnOpenDocunment/OnNewDocument - Document/View 命令处理流程 ID_FILE_NEW CWinApp:OnFileNew() CDocManager:OnFileNew() if(没有文档模板) return; if(有多个文档模板) 弹出对话框让用户选择; 取得模板指针; CMultiDocTemplate:OpenDocumentFile() new 一个文档; 创建子框架; 构建 frame,doc,view 之间的关系; CDocument:OnNewDocume
11、nt() DeleteContents(); InitialUpdateFrame(); return pDoc; ID_FILE_OPEN CWinApp:OnFileOpen() CDocManager:OnFileOpen() CDocManager:DoPromptFileName() CFileDialog:DoModal(); CWinApp:OpenDocumentFile() .选择文档模板; .调整视图和框架; CDocTemplate:OpenDocumentFile(); 判断有无现存文档,是否需要保存 新建框架 判断文件是否存在 CMyDoc:OnOpenDocunme
12、nt() 打开文件; DeleteContents(); 建立 CArchive; Serialize; 关闭 CArchive; ID_FILE_SAVE CDocument:OnFileSave() DoFileSave(NULL) CFileDialog:DoModal(); OnSaveDocument() CArchive; Serialize; *在这里将讲述 SDI 程序中 application object、the main frame window、the document、the view、the document template object 以及 the assoc
13、iate string and menu resources 之间的关系。The Windows Application Object在 CWinApp 派生类的 Implement 文件中会有类似 CMyApp theApp 的语句。theApp 是一个全局变量,它就是启动 MFC 应用程序的机制所在。以下是 MFC 应用程序启动的摘要:1、Windows 把应用程序加载到内存;2、构造全局变量 theApp(所有全局变量在程序被载入内存时被构造) ;3、Windows 调用全局函数 WinMain,它是 MFC 的一部分,等同于无窗口应用程序的 main函数-主程序的入口;4、WinMai
14、n 寻找到 CWinApp 派生类的对象 theApp;5、WinMain 为 theApp 调用 InitInstance 函数,InitInstance 函数可以被重载;6、重载的 InitInstance 函数启动加载 document、显示 the main frame and view windows;7、WinMain 为 theApp 启动 Run 函数,Run 函数负责分派 window messages 和 command messages。The Document Template Class在 CWinApp 派生类的 InitInstance 中会有如下代码:CSing
15、leDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CStudentDoc),RUNTIME_CLASS(CMainFrame), / main SDI frame windowRUNTIME_CLASS(CStudentView);AddDocTemplate(pDocTemplate);这段代码建立了 the application class、the document class、the view window class、the main frame
16、window 四个类之间的联系。这时, application class 的对象已经存在(theApp ) ,但其他四个类的对象还没有构造,MFC 的动态创建机制就起到了作用。一下两个图分别表示了以上四个类之间的关系、四个类的对象之间的关系:Creating an Empty DocumentThe CWinApp:OnFileNew Function当 application class 的 InitInstance 调用完 AddDocTemplate 以后,它将调用 OnFileNew。OnFileNew 做如下事情:1、构造 Document 对象,但不从硬盘中读取数据;2、构造 t
17、he main frame 对象和 the main frame window,但不显示它,它包括IDR_MAINFRAME、the toolbar、the status bar;3、构造 view 对象和 view 窗口,但不显示它;4、建立 the document、main frame、view 对象之间的关系,这里要借助 AddDocTemplate建立的类关系;5、为 document 对象调用虚函数CDocument:OnNewDocument,CDocument:OnNewDocument 函数将调用虚函数DeleteContent 函数;6、为 view 对象调用虚函数 CVi
18、ew:OnInitialUpdate;7、为 frame 对象调用 CFrameWnd:ActivateFrame 以显示 the main frame window(有 the menus,view window,control bars ) 。The Document Classs OnNewDocument Function构造函数所完成的工作越少越好,这样构造函数出错的几率就会越来越小。而CDocument:OnNewDocument 和 CView:OnInitialUpdate 是做初始化的好地方。在这里你可以弹出一个 MessageBox。如果出错,OnNewDocument 还
19、可以返回 FALSE。值得注意的是,OnNewDocument 可以被调用很多次,所以有些指令需只执行一次的话,就需要做一个“first time” flag 成员变量。Connecting File Open to Your Serialization CodeThe OnFileOpen Function文件打开菜单映射到 CWinApp:OnFileOpen 函数,它将执行以下几个步骤:1、提示用户选择一个文件;2、调用虚函数 CDocument:OnOpenDocument,CDocument:OnOpenDocument 打开文件,调用 CDocument:DeleteContent
20、s,并且构造一个 CArchive 对象。随后调用 document 的Serialize 函数从 archive 中载入数据;3、调用 view 的 OnInitialUpdate 函数。Connecting File Save and File Save As to Your Serialization Code文件保存和另存为菜单映射到 CDocument 的 OnFileSave 函数,OnFileSave 函数依次调用Serialize 函数,它使用一个 archive 对象进行存储。The Documents “Dirty“ FlagCDocument 有一个 protected
21、成员函数 m_bModified。可以通过 CDocument 的函数SetModifiedFlag 和 IsModified 访问 m_bModified。当新建一个 document 或者读取完硬盘上的数据后,m_bModified 被 Application Framework 设为 FALSE。当 document 的内容被改写后要确保把 m_bModified 设为 TRUE。小结:OnFileNew 和 OnFileOpen 都在 Application 类中,Application 类里面有DocumentTemplate,可以同时调动 Document 和 View(OnInitialUpdate) 。OnFileSave 和 OnFileSaveAs 都在 Document 类中,它只需做 Serialization,不牵扯 View 的操作,故不需要把它们放在 Application 类中。本文来自 CSDN 博客,转载请标明出处:http:/