3.7如何防止用户关闭一个视图?

来源:互联网 发布:出口海关数据网站 编辑:程序博客网 时间:2024/05/17 22:18

      这一部分讨论了如何创建一个视图,该视图的Close按钮和相关的系统菜单命令都处于失效状态。

第一种技术:

第1步:使用ClassWizard来创建一个新的CMDIChildWnd派生类CNoCloseFrame,该类将实现“不要关闭”的行为。

第2步:使用ClassWizard重载在第1步中创建的类中的LoadFrame()函数,该函数的实现清单如下所示,它使“Close”系统菜单命令失效。

 

第3步:不要忘记在适当的文档模板中引用视图的框架类,以此得到想要的结果。

如果在某些时候,打算关闭那些视图框架窗口的特定窗口,那该怎么办呢?只要简单的调用PostMessage()给窗口发送1条WM_CLOSE消息就行了,如下程序清单:

 

void CNoCloseFrame::OnCloseFrame() 

{

      PostMessage( WM_CLOSE );

}

接着标准的MFC消息处理过程将负责关闭视图的框架窗口并释放相关的文档对象(如果该文档没有其他视图存在)。

 

 

第2中技术:在视图类中处理该行为

在视图类中使用Classwizard重载OnInitialUpdate()虚函数。该函数的实现如下面的程序清单所示,它使父框架窗口的“Close”系统菜单命令失效。

如同在第一种技术中解释的那样,可以调用PostMessage给视图的父框架窗口发送一条WM_CLOSE消息来关闭这些视图中某个特定是视图。

解释:

在什么时候调用LoadFrame()函数呢?该函数实际上执行了什么操作呢?要回答这些问题,我们需要深入到MFC内部,该过程使用 文档模板对象 创建视图窗口。该过程采用 4步构造处理 来创建框架窗口的C++对象 和 与其 关联的Windows窗口。

1、MFC调用 文档模板对象 的CreateNewFrame()函数

2、CreateNewFrame()通过调用 动态创建函数 CreateObject()来创建 合适的框架窗口 C++对象

3、接着CreateNewFrame()函数调用 框架窗口的LoadFrame()函数

4、LoadFrame()函数创建Windows窗口 并 链接相关的资源(资源模板ID)

CMDIChildWnd::LoadFrame()函数,它是与我们的讨论关系最为紧密的函数。然而,MFC还为CFrameWnd和CMDIFrameWnd类定义了不同的LoadFrame()实现。

当使用标准的“File->New”菜单命令创建一个新的文档对象时,调用LoadFrame函数的调用链如下:

CWinApp()::OnFileNew()=>CDocManager::OnFileNew()=>CMultiDocTemplate::OpenDocumentFile()=>CDocTemplate::CreateNewFrame()=>CNoCloseFrame::LoadFrame();

如果使用标准的“Windows->New Window”菜单命令为一个已有的文档创建新视图,那么函数调用链如下:

CMDIFrameWnd::OnWindowNew()=>CDocTemplate::CreateNewFrame()=>CNoCloseFrame::LoadFrame();

附加注释:

注意:前面的技术并不完全能够阻止用户的行为:如果用户按下ctrl+F4组合键或者退出应用程序时,仍然可以关闭视图。如果打算不惜一切代价阻止这种行为,或者保留“close”按钮有效,那么应该考虑使用下面两种技术中的一种:

1)在视图的框架窗口类中处理WM_CLOSE消息,并决定是否允许窗口关闭,如下面的程序清单:

 

2)在文档类中使用ClassWizard重载CDocument::CanCloseFrame()函数,程序清单如下所示:

 

如果决定使用后面这种技术,则应该意识到,是在文档 试图关闭 框架 之前调用的CDocument::CanCloseFrame();函数,而不是在通常的文档关闭过程之后(如果框架碰巧包含了所打开的特定文档的最后一个视图)。因此,当试图关闭文档的最后一个子窗口时,在调用CDocument::CanCloseFrame();函数前将提示用户保存文档。有时候,这可能导致奇怪的行为。

 

 

 

原创粉丝点击