来自 澳门金莎娱乐手机版 2019-11-14 16:49 的文章
当前位置: 金沙澳门官网网址 > 澳门金莎娱乐手机版 > 正文

澳门金莎娱乐手机版模态对话框与非模态对话的

前几天发现自己的程序中使用非模态对话框,Debug版本有警告提示如下:

总结OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别(转)

Warning: calling DestroyWindow in CWnd::~CWnd OnDestroy or PostNcDestroy in derived class will not be called

2009年09月22日 下午 08:33

由于是Warnning,就没有太在意,后来随意上网一找发现,这个问题还是很严重的问题。

第一,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和OnDestroy()是CWnd基类的成员函数,即WM消息响应函数。从应用程序结构的角度,拿对话框来说,红色的X对应的是CWnd,而处于对话框中的“确定”、“取消”按钮则对应了CDialog。

最后,发现有些基本问题我还没有搞清楚。同时在这个过程中,也学习了不少新东西,网上关于这个问题的资料很多,感觉真正把问题讲清楚的不多。今天我就来个总结,同时,也把网上有些人的疑问给解答下,更重要的是自己以后忘记了,可以回来参考。

第二,OnClose()和OnDestroy()

 

在单视图程序中,根据<<深入浅出MFC>>所讲,程序退出时执行的操作顺序为(从点X按钮开始)
(1)用户点击X退出按钮,发送了WM_CLOSE消息----->响应OnClose()
(2)在WM_CLOSE消息的处理函数中,调用DestroyWindow()----->销毁与指定CWnd窗口对象关联的窗口,但未销毁CWnd对象
(3)在DestroyWindow()中发送了WM_DESTROY消息----->窗口销毁后响应OnDestroy()
(4)在WM_DESTROY消息中调用PostQuitMessage(),发送WM_QUIT消息,结束消息循环

先说下模式对话框调用的原则。就是一定要先关了这个对话框才能操作后面窗口的对话框)

可以看到,程序的退出过程,是先响应OnClose(),然后响应OnDestroy(),在响应OnDestroy()之前,窗口对象已经被销毁。OnDestroy()到底干了什么呢?它就像一个teller,先通知CWnd对象告诉它即将被销毁,尔后OnDestroy的真正运行是在CWnd对象已经从屏幕上清除以后被调用的。

模式对话框下,用CDialog::OnOK()或CDialog::OnCancel()以及CDialog::OnClose()关闭对话框。

第三,OnOK()、OnCancel()()、OnClose()、OnDestroy()

一定要注意之前的CDialog::当然,你可以重载你自己对话框的这个虚函数,但是,后面必须调用基类的CDialog::

CDialog::OnOK首先调用UpdateData(TRUE)将数据传给对话框成员变量,然后调用CDialog::EndDialog关闭对话框;  
CDialog::OnCancel只调用CDialog::EndDialog关闭对话框;  
OnClose()是响应   WM_CLOSE   的.一定程度上可以说CDialog::EndDialog()和OnClose()完成类似的工作,但处理的机制不一样,前者是CDialog的对象机制,后者是WM的消息映射机制。

具体我们再参照深入浅出的风格,来个解刨。 

CDialog::EndDialog()-------->OnDestroy()

CDialog::Close()默认调用CDialog::OnCancel() , CDialog::OnCancel()调用CDialog::EndDialog(IDCANCEL);

                 OnClose()-------->OnDestroy()

CDialog::EndDialog调用CDialog::DestroyWindows(),CDialog::DestroyWindows调用CDialog::OnDestroy() ;

EndDialog()和OnClose()属于“同级别”的,所以我们在按下OK按钮的时候,程序是不会执行OnClose()的,但两种机制都必须经过OnDestroy()

CDialog::OnOK()默认先CDialog::UpdateData(),然后再调用CDialog::EndDialog(IDOK).

本文来自CSDN博客,转载请标明出处:

CDialog::EndDialog调用CDialog::DestroyWindows(), CDialog::DestroyWindows调用CDialog::OnDestroy()   

 

看来上面你可能就知道了如下的等式

 

CDialog::Close() == CDialog::OnCancel() == CDialog::EndDialog(IDCANCEL)一样。

然后发现

CDialog::OnOK() == CDialog::EndDialog(IDOK).

下面这两种说法不明晰

CDialog::EndDialog(IDOK)跟CDialog::EndDialog(IDCANCEL)的区别就是,少了一个CDialog::UpdateData(),也就是CDialog::EndDialog(IDOK),在关闭对话框后,会把对话框上控件关联的变量的值更新为用户最后输入的值。而CDialog::EndDialog(IDCANCEL)就不会更新这个值。

(1) EndDialog(-1);
关闭模态对话框,并且将参数作为父对话框调用的返回值。
(2)  DestroyWindow();  ::PostQuitMessage(0);
DestroyWindow 关闭非模态对话框。 退出消息循环,真正结束进程。有不少程序窗口关闭,但是不等于退出运行。

希望自己把模式对话框的关闭讲清楚了。

 

本文由金沙澳门官网网址发布于澳门金莎娱乐手机版,转载请注明出处:澳门金莎娱乐手机版模态对话框与非模态对话的

关键词: