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类中。

时间: 2024-10-23 10:33:52

VC菜单命令详解(文件打开、保存与关闭)的相关文章

BAT批处理之文件与文件夹操作代码(附xcopy命令详解)_DOS/BAT

批处理中的文件.文件夹操作,xcopy命令的用法. 一,建bat文件自动执行复制,删除命令. 例1:复制cd.dll文件至windows\system32的bat文件内容: 复制代码 代码如下: copy cd.dll %windir%\system32 例2:卸载windows\system32目录中的cd.dll,即把上面复制的文件删除: 复制代码 代码如下: del %windir%\system32\cd.dll 例3:删除download文件夹中的文件,例子如下: 复制代码 代码如下:

一天一个shell命令 linux文件操作系列-ln命令详解_linux shell

里提示一下:ubuntu的翻译很多都是字面直译,存在很多问题,所以建议大家参照我这里的解释.当然本来也是有些赶文的嫌疑,望指正. 经常在linux上操作,有在不同的目录下切换某几个固定的命令,或者修改几个固定的文件,这时候,如果能在一个目录下就操作他们,会是一件多么轻松的事情.我们来看看链接命令ln 全称 ln 全称是link 顾名思义,这是一个建立一个链接.怎么去理解呢?它的功能类似于Mac OS的别名或者Windows的快捷方式, 删除不会影响文件本身. 说明:(直接看看斜体,就行了) 链接

浅析memcache启动以及telnet命令详解

1.启动Memcache 常用参数 复制代码 代码如下: -p <num> 监听的TCP端口(默认: 11211) -U <num> UDP监听端口 (默认: 11211, 0 时关闭) -d 以守护进程方式运行 -u <username> 运行运行 Memcached的账户 非root用户 -m <num> 最大的内存使用单位是MB 默认是64MB -c <num> 软连接数量默认是1024 -v 输出警告和错误信息 -vv 打印客户端的请求和

linux yum命令详解

yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载.安装.yum提供了查找.安装.删除某一个.一组甚至全部软件包的命令,而且命令简洁而又好记. yum的命令形式一般是如下:yum [options] [command] [package ...] 其中的[opt

VirtualBox下配置串口以及stty命令详解(原创)

虚拟机于主机通过串口通信  我们需要先配置一下宿主机器上的virtualbox. 1. 在串口栏中勾选 []启用串口(E) 2. 端口编号选择COM1 3. 端口模式选择Host Pipe 4. 勾选 []创建通道(C) 5. Port/File Path: 填上 /tmp/serial. 也就是说我们在宿主机器的/tmp/中创建了serial的通道文件 此外,我们还要在宿主机器上设定一下串口.在此之前需要安装minicom软件 1. 运行minicom -s命令 2. CTRL+A调出配置界面

批处理命令 For循环命令详解

批处理for命令详解 FOR这条命令基本上都被用来处理文本,但还有其他一些好用的功能! 看看他的基本格式(这里我引用的是批处理中的格式,直接在命令行只需要一个%号) FOR 参数 %%变量名 IN (相关文件或命令) DO 执行的命令 参数:FOR有4个参数 /d /l /r /f 他们的作用我在下面用例子解释 %%变量名 :这个变量名可以是小写a-z或者大写A-Z,他们区分大小写,FOR会把每个读取到的值给他; IN:命令的格式,照写就是了; (相关文件或命令) :FOR要把什么东西读取然后赋

linux 下的yum命令详解_Linux

yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载.安装.yum提供了查找.安装.删除某一个.一组甚至全部软件包的命令,而且命令简洁而又好记. yum的命令形式一般是如下:yum [options] [command] [package ...] 其中的[opt

linux定时执行命令crontab命令详解

循环运行的例行性计划任务,linux系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的.另外, 由于使用者自己也可以设置计划任务,所以, Linux 系统也提供了使用者控制计划任务的命令 :crontab 命令.   一.crond简介   crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启

DOS批处理高级教程 第二章 DOS循环for命令详解_DOS/BAT

讲FOR之前呢,咋先告诉各位新手朋友,如果你有什么命令不懂,直接在CMD下面输入: name /? 这样的格式来看系统给出的帮助文件,比如for /? 就会把FOR命令的帮助全部显示出来!当然许多菜鸟都看不懂....所以才会有那么多批处理文章!!!!俺也照顾菜鸟,把FOR命令用我自己的方式说明下! 正式开始: 一.基本格式 FOR %%variable IN (set) DO command [command-parameters] %%variable 指定一个单一字母表示可替换的参数. (s