`
testcs_dn
  • 浏览: 114591 次
  • 性别: Icon_minigender_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判断文档模板是否多于一个,是则显示文档类型对话框(AFX_IDD_NEWTYPEDLG)
让用户选择要创建的文档类型。然后调用CDocTemplate::OpenDocumentFile(NULL)。
|
CDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMake_Visible=TRUE)对于SDI和MDI的
处理不一样。

对于SDI,1,若已有文档打开,对其重新初始化,调用CDocument::SaveModified()保存当前文档;若没
有文档存在,则调用CreateNewDocument()创建文档对象,再调用CreateNewFrame(pDoucment,NULL)创建
文档的框架窗口。2,若lpszPathName为NULL,则调用CDocument::OnNewDocument()处理新文档,用
pDocument->SetPathName(lpszPathName)设置文档的路径。3,判断当前线程主框架窗口是否存在,不存
在则将1中创建的新框架作为主框架。4,调用InitialUpdateFrame显示框架窗口。

对于MDI,与SDI基本相同,但是没有第3步。
|
CDocument::OnNewDocument()首先调用DeleteContents()删除原文档内容,使用m_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::OpenDocumentFile(LPCTSTR lpszFileName)遍历文档模板,对每个模板用
MatchDocType(szPath,pOpenDocument)匹配文档类型。匹配时主要根据文件扩展名判断。若文件已经在
某个文档中打开,则激活文档的第一个视图,否则用匹配的文档模板pBestTemplate->OpenDocumentFile
(szPath)。
|
CDocTemplate::OpenDocumentFile调用CDocument::OnOpenDocument打开文件。
|
CDocument::OnOpenDocument打开文件,用DeleteContents删除现有文档内容,创建文件对应的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 lpszPathName,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,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()保存文件。
|
CDocument::OnCloseDocument()首先销毁文档框架,再用DeleteContents()删除文档内容,若m_
bAutoDelete则delete this。

第二部分:

MDI打开文件的过程
CWinApp::OnFileOpen()
{
CDocManager::OnFileOpen()
{
CDocManager::DoPromptFileName()
{
CFileDialog::DoModal();
}
CWinApp::OpenDocumentFile()
{
...选择文档模板;
...调整视图和框架;
CDocTemplate::OpenDocumentFile();
{
判断有无现存文档,是否需要保存
新建框架
判断文件是否存在,调用CMyDoc::OnOpenDocunment/OnNewDocument
}
}
}
}
----------------------------------------
Document/View命令处理流程
ID_FILE_NEW
CWinApp::OnFileNew()
{
CDocManager::OnFileNew()
{
if(没有文档模板)
return;
if(有多个文档模板)
{
弹出对话框让用户选择;
取得模板指针;
}
CMultiDocTemplate::OpenDocumentFile()
{
new一个文档;
创建子框架;
构建frame,doc,view之间的关系;
CDocument::OnNewDocument()
{
DeleteContents();
}
InitialUpdateFrame();
return pDoc;
}
}
}

ID_FILE_OPEN
CWinApp::OnFileOpen()
{
CDocManager::OnFileOpen()
{
CDocManager::DoPromptFileName()
{
CFileDialog::DoModal();
}
CWinApp::OpenDocumentFile()
{
...选择文档模板;
...调整视图和框架;
CDocTemplate::OpenDocumentFile();
{
判断有无现存文档,是否需要保存
新建框架
判断文件是否存在
CMyDoc::OnOpenDocunment()
{
打开文件;
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 associate 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、WinMain寻找到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中会有如下代码:
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CStudentDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CStudentView));
AddDocTemplate(pDocTemplate);
这段代码建立了the application class、the document class、the view window class、the main frame window四个类之间的联系。这时,application class的对象已经存在(theApp),但其他四个类的对象还没有构造,MFC的动态创建机制就起到了作用。
一下两个图分别表示了以上四个类之间的关系、四个类的对象之间的关系:



Creating an Empty Document—The CWinApp::OnFileNew Function
当application class的InitInstance调用完AddDocTemplate以后,它将调用OnFileNew。
OnFileNew做如下事情:
1、构造Document对象,但不从硬盘中读取数据;
2、构造the 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对象调用虚函数CView::OnInitialUpdate;
7、为frame对象调用CFrameWnd::ActivateFrame以显示the main frame window(有the menus,view window,control bars)。

The Document Class's OnNewDocument Function
构造函数所完成的工作越少越好,这样构造函数出错的几率就会越来越小。而CDocument::OnNewDocument 和 CView::OnInitialUpdate 是做初始化的好地方。在这里你可以弹出一个MessageBox。如果出错,OnNewDocument还可以返回FALSE。值得注意的是,OnNewDocument可以被调用很多次,所以有些指令需只执行一次的话,就需要做一个“first time” flag成员变量。

Connecting File Open to Your Serialization Code—The OnFileOpen Function
文件打开菜单映射到CWinApp::OnFileOpen函数,它将执行以下几个步骤:
1、提示用户选择一个文件;
2、调用虚函数CDocument::OnOpenDocument,CDocument::OnOpenDocument打开文件,调用CDocument::DeleteContents,并且构造一个CArchive对象。随后调用document的Serialize函数从archive中载入数据;
3、调用view的OnInitialUpdate函数。

Connecting File Save and File Save As to Your Serialization Code
文件保存和另存为菜单映射到CDocument的OnFileSave函数,OnFileSave函数依次调用Serialize函数,它使用一个archive对象进行存储。

The Document's "Dirty" Flag
CDocument有一个protected成员函数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类中。

分享到:
评论

相关推荐

    VC++无法打开文件和向工程中添加文件的解决办法

    ### VC++无法打开文件和向工程中添加文件的解决办法 #### 一、问题背景 在使用VC++进行软件开发的过程中,部分用户遇到了无法打开文件和无法向工程中添加文件的问题。这一问题不仅影响了开发效率,也增加了开发者...

    vc深入详解

    - **文件对话框**:使用文件打开和保存对话框让用户选择文件。 #### Lesson13: 文档串行化 - **数据持久化**:将文档数据保存到磁盘或从磁盘加载。 - **序列化技术**:使用MFC的CDocument类实现文档数据的序列化。 ...

    安装vc运行库Error1935解决办法

    5. **执行系统文件检查**:重启后,以管理员身份打开命令提示符窗口,并输入命令`SFC /SCANNOW`,启动系统文件检查工具。该工具将自动扫描系统文件并修复损坏或缺失的部分。请注意,此过程可能需要几分钟的时间才能...

    vc6.0快捷键

    ### vc6.0快捷键详解 #### 一、概述 Visual C++ 6.0(简称VC6.0)是一款由微软开发的经典集成开发环境(IDE),主要用于C/C++语言程序的编写与调试。在软件开发过程中,熟练掌握并运用快捷键能够极大地提高工作...

    \VC6.0中MFC生成.exe安装包步骤.

    ### VC6.0中MFC生成.exe安装包步骤详解 #### 一、前言 在软件开发领域,尤其是对于基于Microsoft Foundation Classes (MFC)框架的应用程序开发而言,如何将开发完成的应用程序打包成安装包是至关重要的一步。本文...

    多文档窗口视图VC 实现.rar

    源码中可能包含了打开、保存、关闭文档的实现,以及如何在内存中管理这些文档的数据。 8. **编译与运行**:使用VC++ 6.0环境,开发者可以编译并运行此源码,以实际体验和测试这个多文档窗口视图的功能和交互。 综...

    matlab6.5 + vc6配置编程方法

    ### MATLAB 6.5 与 VC6 配置编程详解 #### 一、概述 本文主要针对较旧版本的 Visual C++ 6.0 (简称 VC6) 和 MATLAB 6.5 的安装、环境搭建以及系统配置进行了详细介绍,并提供了一些基本的命令提示方法。 #### 二...

    VC学习大纲 VC学习讲义

    - **CFileDialog类的使用**:用于打开文件对话框或保存文件对话框。 - **CFile、fstream、CArchive类的使用与比较**:这些类提供了不同的文件读写方式。 - **const char *与char * const的区别**:前者是指向常量...

    VC6实用技巧分析说明

    【VC6.0实用技巧详解】 在VC6.0编程环境中,掌握一些实用技巧能够显著提升开发效率。以下是一些关键技巧的详细说明: 1. **括号匹配检查**:在编写代码时,确保括号匹配是至关重要的。将光标放在任何括号前,按下...

    VC Studio 使用技巧大全

    ### VC Studio 使用技巧详解 #### 1. 检测程序中的括号匹配 在VC Studio中,检测括号(包括大括号`{}`、方括号`[]`、圆括号`()`和尖括号`<>`)是否匹配是一项重要的功能。只需将光标置于目标括号前,按下快捷键`...

    ParGen-VC设置

    ### ParGen-VC设置详解 #### 一、概述 本文主要介绍了如何在Visual C++ (VC++)环境中配置和使用由Bumble-Bee Software公司开发的ParserGenerator工具。ParserGenerator是一款功能强大的集成环境,用于实现YACC ...

    AutoCAD编程技巧

    - 当用户发出菜单命令时,AutoCAD会按照以下顺序加载菜单文件: 1. 加载指定菜单名的 `.mnc` 文件。 2. 如果找不到 `.mnc` 文件,则尝试加载同名的 `.mns` 文件,并将其编译成 `.mnc` 文件。 3. 如果 `.mnc` 和 ...

    FileTool源码

    - 在VC IDE中,插件需要监听IDE的事件,如文件打开、关闭、保存等,然后相应地执行自定义操作。 - 源码中会有事件处理函数,这些函数会被IDE调用,以实现插件功能的触发。 5. **错误处理和日志记录** - 良好的...

    WinDBG调试技巧

    《WinDBG调试技巧详解》 WinDBG,全称Debugging Tools for Windows,是一款强大的调试工具,尤其在处理底层系统和驱动程序的调试方面表现出色。它根据不同的CPU指令架构提供了x86、AMD64和IA64三个版本。WinDBG不仅...

    用VC++打造自己的资源管理器

    - **菜单项功能**: 菜单项包括打开、关闭、复制、剪切、粘贴、删除等功能,这些操作都是通过调用相应的Windows API函数来实现的。 - **菜单项用途**: 比如`IDM_FILE_OPEN`用于打开目录,`IDM_EDIT_PASTE`用于粘贴...

    Visual C实战.doc

    在复制文件前需要关闭VC以确保文件完整。 - **.opt**:临时文件,用于存储用户的设置信息。 - **.plg**:临时文件,具体用途视具体插件而定。 #### 二、工具条自定义与使用 在Visual C++中,工具条的自定义可以极...

    VCEDIt 行距

    - **通用对话框**:MFC提供了一系列通用对话框,如文件打开/保存对话框、颜色选择对话框等。 **5.8 建立以对话框为基础的应用** - **对话框式应用**:基于对话框的应用程序是一种常见的应用程序架构,它将用户界面...

    利用MFC ODBC操作Access数据库实现显示、添加、修改、删除等功能

    2. 定义好表格后,保存并关闭Access,确保数据库文件已创建并保存在适当的位置。 **二、配置ODBC数据源** 1. 在Windows系统中,通过控制面板的“管理工具”打开“数据源(ODBC)”。 2. 在ODBC数据源管理器中,选择...

    MFC各种详解

    根据提供的文件信息,我们可以从中提炼出与MFC(Microsoft Foundation Classes)相关的多个知识点。MFC是微软提供的一套用于简化Windows编程的类库,广泛应用于C++开发中。以下是对这些知识点的详细解读: ### 1. ...

Global site tag (gtag.js) - Google Analytics