第6章 应用程序的退出.pdf

上传人:qwe****56 文档编号:74646793 上传时间:2023-02-27 格式:PDF 页数:6 大小:104.22KB
返回 下载 相关 举报
第6章 应用程序的退出.pdf_第1页
第1页 / 共6页
第6章 应用程序的退出.pdf_第2页
第2页 / 共6页
点击查看更多>>
资源描述

《第6章 应用程序的退出.pdf》由会员分享,可在线阅读,更多相关《第6章 应用程序的退出.pdf(6页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、第 6 章 应用程序的退出 第 6 章 应用程序的退出 一个 Windows 应用程序启动之后,一般是进入消息循环,等待或者处理用户的输入,直到用户关闭应用程序窗口,退出应用程序为止。例如,用户按主窗口的关闭按钮,或者选择执行系统菜单“关闭”,或者从“文件”菜单选择执行“退出”,都会导致主窗口被关闭。当用户从“文件”菜单选择执行“退出”时,将发送 MFC 标准命令消息 ID_APP_EXIT。MFC 实现了函数 CWinApp:OnAppExit()来完成对该命令消息的缺省处理。void CWinApp:OnAppExit()/same as double-clicking on main w

2、indow close box ASSERT(m_pMainWnd!=NULL);m_pMainWnd-SendMessage(WM_CLOSE);可以看出,其实现是向主窗口发送 WM_CLOSE 消息。主窗口处理完 WM_CLOSE 消息之后,关闭窗口,发送 WM_QUIT 消息,退出消息循环(见图 5-3),进而退出整个应用程序。6.1 边框窗口对WM_CLOSE的处理 6.1 边框窗口对WM_CLOSE的处理 MFC 提供了函数 CFrameWnd:OnClose 来处理各类边框窗口的关闭:不仅包括 SDI 的边框窗口(从 CFrameWnd 派生),而且包括 MDI 的主边框窗口(从

3、CMDIFrameWnd 派生)或者文档边框窗口(从 CMDIChildWnd 派生)的关闭。该函数的原型如下,流程如图 6-1 所示:void CFrameWnd:OnClose()从图 6-1 中可以看出,它首先判断是否可以关闭窗口(m_lpfnCloseProc 是函数指针类型的成员变量,用于打印预览等情况下),然后,根据具体情况进行处理:?如果是主窗口被关闭,则关闭程序的所有文档,销毁所有窗口,退出程序;?如果不是主窗口被关闭,则是文档边框窗口被关闭,又分两种情况:若该窗口所显示的文档被且仅被该窗口显示,则关闭文档和文档窗口并销毁窗口;若该窗口显示的文档还被其他文档边框窗口所显示,则仅

4、仅关闭和销毁文档窗口。(m_lpfnCloseProc!=NULL&!(*m_lpfnCloseProc)(this)TRUE,则不能关闭窗口,返回,否则,继续 为获取活动文档对象 pDocument GetActiveDocument CFrameWnd的成员函数 GetActiveDocument 虚拟函数 得到活动视 pView GetActivateView 得到活动视的文档pView-GetDocum ent()如 pDocument 非空,询问是否可以关闭该边框窗口;若不能就返回,否则,继续 pDocument-CanCloseFrame CDocument 的CanCloseFr

5、ame个边框窗口显示该文档,回 TRUESaveModified虚 拟 成 员 函 数检查是否多于一是则返,否则调用虚拟函数保存文档 保存所有的文档 pApp-SaveAllModified CWinApp 的虚拟成员SaveAllModified函数关闭文档前隐藏程序的窗口pApp-HideApplication CWinApp 的成员函数HideApplication 关闭程序所有的文档 pApp-CloseAllDocuments CWinApp 的成员函数CloseAllDocuments 若主窗口已经销毁(NULL)且不是 DLL 模块,则发送消息WM_QUIT 后返回,否则继续Y

6、N 应用程序的主窗口是要关闭的该窗口吗?下面是处理 WM_CLOSE 消息中涉及的一些函数。YN关闭文档窗口,然后返回pDocument-OnCloseDocument()通知文档准备关闭窗口 pDocument-PreCloseFrame(this)CDocument 的 虚拟 成 员 函 数OnCloseDocumentCD拟Procument 的 虚成 员 函 数eCloseFrame销毁窗口DestroyWindow()MFC为 类CWnd、CMDIChildWnd实 现DestroyWindow;WM_DESTROY 和 WM或者 WM_QUIT 消息CControlBar、了 虚

7、拟 函 数它将导致_NCDESTROY发送给将销毁的窗口。NY图 6-1 CFrameWnd 的 OnClose 函数活动文档存在且属性自动删除为(pDocument!=NULL&pDocument-m_bAutoDelete)真该边框窗口是否显示活动文档的最后一个边框窗口?BOOL CDocument:SaveModified()该虚拟函数的缺省实现:首先调用 IsModifed 判断文档是否被修改,没有修改就返回,否则继续。当询问用户是否保存被修改的文档时,若用户表示“cancel”,返回 FALSE;若用户表示“no”,则返回 TRUE;若用户表示“yes”,则存盘失败返回 FALSE,

8、存盘成功返回 TRUE。存盘处理首先要得到被保存文件的名称,然后调用虚拟函数 OnSaveDocument 完成存盘工作,并使用 SetModifidFlag(FALSE)设置文档为没有修改。?BOOL CDocument:OnSaveDocument(LPCTSTR lpszPathName)该函数是虚拟函数,用来保存文件。其实现的功能和 OpOpenDocument 相反,但处理流程类似,描述如下:根据 lpszPathName 打开文件 pFile;使用 pFile 构造一个用于写入数据的 CArchive 对象,此对象用来保存数据到文件;设置鼠标为时间瓶形状;使用 Serialize

9、函数完成序列化写;完毕,恢复鼠标的形状。?CWinApp:SaveAllModified()CWinApp:CloseAllDocuments(BOOL bEndSession)这两个函数都遍历模板管理器列表,并分别对列表中的模板管理器对象逐个调用CDocManager 的同名成员函数:CDocManager:SaveAllModified()CDocManager:CloseAllDocuments(BOOL bEndSession)这两个函数都遍历其文档模板列表,并分别对列表中的模板对象逐个调用 CDocTemplate 的同名成员函数:CDocTemplate:SaveAllModifi

10、ed()CDocTemplate:CloseAllDocuments(BOOL bEndSession)这两个函数都遍历其文档列表,并分别对列表中的文档对象逐个调用 CDocuemnt 的成员函数:CDocument:SaveModified()CDocument:OnCloseDocument()?CDocument:SaveModified()CDocument:OnCloseDocument()CDocument:SaveModified 前面已作了解释。OnCloseDocument 是一个虚拟函数,其流程如图 6-2 所示。通过文档对象所对应的视,得到所有显示该文档的边框窗口的指针:

11、在 SDI 程序关闭窗口时,获取的是主边框窗口;在 MDI 程序关闭窗口时,获取的是 MDI 子窗口。然后,关闭并销毁对应的边框窗口。如果文档对象的 m_bAutoDelete 为真,则销毁文档对象自身。保存 m_bAutoDelete遍历视列表 m_viewList:获取视窗口所在的边框窗口 pFrame准备关闭边框窗口:PreCloseFrame(pFrame)销毁边框窗口:pFrame-DestroyWindow()恢复 m_bAutoDelete删除文档内容DeleteContents如果 m_bAutoDelete 为 TRUE销毁 MFC 文档对象:delete this图 6-2

12、 CDocument 的 OnCloseDocument函数CDocument 的 虚拟函数PreCloseFrame,MFC 缺省实现空CFrameWnd 的虚拟函数DestroyWidnowCDocDeleument 的虚拟函数teContents 6.2 窗口的销毁过程 6.2 窗口的销毁过程 6.2.1 DestroyWindow 从图 6-1、图 6-2 可以看出,销毁窗口是通过调用 DestroyWindow 来完成的。DestroyWindow是 CWnd 类的一个虚拟函数。CWnd 实现了该函数,而 CMDIChildWnd 覆盖了该函数。(1)CWnd:DestroyWind

13、ow()主要就是调用:DestroyWindow 销毁 m_hWnd(必须非空),同时销毁其菜单、定时器,以及完成其他清理工作。:DestroyWindow 使将被销毁的窗口失去激活、失去输入焦点,并发送 WM_DESTROY、WM_NCDESTROY 消息到该窗口及其各级子窗口。如果被销毁的窗口是子窗口且没有设置WM_NOPARENTNOTFIY 风格,则给其父窗口发送 WM_PARENTNOFITY 消息。(2)CMDIChildWnd:DestroyWindow()因为 MDI 子窗口不能使用:DestroyWindows 来销毁,所以 CMdiChildWnd 覆盖了该函数,CMDIC

14、hildWnd 主要是调用成员函数 MDIDestroy 给客户窗口(父窗口)发送消息WM_MDIDESTROY,让客户窗口来销毁自己。6.2.2 处理处理WM_DESTROY消息消息 消息处理函数 OnDestroy 处理 WM_DESTROY 消息,CFrameWnd、CMDIChildWnd、CWnd、CView 及其派生类(如 CEditView 等等)、CControlBar 等都提供了对该消息的处理函数。这里,主要解释边框、文档边框、视类的消息处理函数 OnDestroy。(1)CWnd:OnDestroy()调用缺省处理函数 Default()。(2)CFrameWnd:OnDe

15、stroy()首先,销毁工具栏的窗口;然后,设置菜单为缺省菜单;接着,如果要销毁的是主边框窗口,则通知 HELP 程序本应用程序将退出,没有其他程序使用 WINHELP 则关闭 WINHELP;最后调用 CWnd:OnDestroy。(3)CMDIFrameWnd:OnDestroy()首先,调整客户窗口的边界类型;然后,调用基类 CframeWnd 的 OnDestroy。这时,MDI子窗口的工具栏窗口列表为空,故没有工具栏窗口可以销毁。(4)CView:OnDestroy()首先,判断自身是否是边框窗口的活动视,如果是则调用边框窗口的 SetActivateView 使自己失去激活;然后,

16、调用基类 CWnd 的 OnDestroy。6.2.3 处理处理WM_NCDESTROY消息消息 窗口的非客户区被销毁时,窗口接收 WM_NCDESTROY 消息,由 OnNcDestroy 处理WM_NCDESTROY 消息。在 MFC 中,OnNcDestroy 是 Windows 窗口被销毁时调用的最后一个成员函数。CWnd、CView 的某些派生类提供了对该消息的处理函数,这里只讨论 CWnd 的实现。(1)CWnd:OnNcDestroy()首先判断当前线程的主窗口是否是该窗口,如果是且模块非 DLL,则发送 WM_QUIT 消息,使得程序结束;然后,判断当前线程的活动窗口是否是该窗

17、口,如果是则设置活动窗口为 NULL;接着,清理 Tooltip 窗口,调用 Default 由 Windows 缺省处理 WM_NCDESTROY 消息,UNSUBCLASS,把窗口句柄和 MFC 窗口对象分离(Detach);最后,调用虚拟函数 PostNcDestoy。(2)PostNcDestoy CWnd、CFrameWnd、CView、CControlBar 等都覆盖了该函数。文档边框窗口和边框窗口都使用 CFrameWnd:PostNcDestroy。?CWnd:PostNcDestroy()MFC 缺省实现空?void CFrameWnd:PostNcDestroy()调用 d

18、elete this 销毁自身这个 MFC 对象。?void CView:PostNcDestroy()调用 delete this 销毁自身这个 MFC 对象。(3)析构函数 delete this 导致析构函数的调用。需要提到的是 CFrameWnd 和 CView 的析构函数。?CFrameWnd:CFrameWnd()边框窗口在创建时,把自身加入到模块-线程状态的边框窗口列表 m_frameList 中。现在,从列表中移走该窗口对象。必要的话,删除 m_phWndDisable 数组。?CView:CView()在视创建时,把自身加入到文档对象的视列表中。现在,从列表中移走该视对象。应

19、用程序调用 CloseAllDocument 关闭文档时。参数为 FALSE,它实际上并没有把视从列表中清除,而最后的清除是由析构函数来完成的。至此,边框窗口关闭的过程讨论完毕。下面,结合具体情况SDI 窗口的关闭、MDI 主窗口的关闭、MDI 子窗口的关闭描述对 WM_CLOSE 消息的处理。6.3 SDI窗口、MDI主、子窗口的关闭 6.3 SDI窗口、MDI主、子窗口的关闭 参考图 6-1 分析 SDI 窗口、MDI 主、子窗口的关闭流程。(1)SDI 窗口的关闭 在这种情况下,主窗口将被关闭。首先,关闭应用程序的文档对象。文档对象的虚拟函数OnCloseDocument 调用时销毁了主

20、窗口(Windows 窗口和 MFC 窗口对象),同时也导致视、工具条窗口的销毁。主窗口销毁后,应用程序的主窗口对象为空,故发送 WM_QUIT 消息结束程序。(2)MDI 主窗口的关闭 首先,关闭应用程序的所有文档对象。文档对象的 OnCloseDocument 函数关闭文档时,将销毁文档对象对应的文档边框窗口和它的视窗口。这样,所有的 MDI 子窗口(包括其子窗口视)被销毁,但应用程序的主窗口还在。接着,调用 DestroyWindow 成员函数销毁主窗口自身,DestroyWindow 发现被销毁的是应用程序的主窗口,于是发送 WM_QUIT 消息结束程序。(3)MDI 子窗口(文档边框窗口)的关闭 在这种情况下,被关闭的不是主窗口。判断与该文档边框窗口对应的文档对象是否还被其他一个或者多个文档边框窗口使用,如果是,则仅仅销毁该文档边框窗口(包括其子窗口视);否则,关闭文档,文档对象的 OnCloseDocument 将销毁该文档边框窗口(包括其子窗口视)。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com