您的位置:首页 > 其它

关于对话框销毁的讨论解决另外我的问题

2008-10-06 13:03 375 查看
详见帖子:http://topic.csdn.net/t/20050522/01/4025795.html

1楼:

我见N多资料都在强调非模态对话框只能在堆上分配空间,这个我明白。它们又强调要调用调用DestroyWindow()以达到彻底销毁自身对象的作用,因为DestroyWindow()的调用会引起OnDestroy()的调用,在OnDestroy函数中delete this。

说的都很有道理。但是他们都不约而同的把DestroyWindow()函数的调用位置塞进了OnOk()和OnCancel()中了。

我的问题:假如一个对话框,空空的,没有OK也没有Cancel,只有标题栏上有个"关闭"的系统按钮,现在我该怎么销毁new的非模态对话框呢???地球人都知道系统按钮"关闭",对应的消息是WM_CLOSE,在OnClose的消息处理函数中,会继续调用CDialog::OnClose,一直都没调用DestroyWindow()哎,delete this应该放在哪里?????????

2楼:
球人都知道系统按钮"关闭",对应的消息是WM_CLOSE
=============
呵呵,你恰恰就是这里错了.系统按钮"关闭"对应的消息并不是WM_CLOSE,而是WM_SYSCOMMAND,而wParam参数指明了 是何种类型:关闭按钮为: SC_CLOSE

WM_SYSCOMMAND
A window receives this message when the user chooses a command from the window menu (formerly known as the system or control menu) or when the user chooses the maximize button, minimize button, restore button, or close button

SC_CLOSE Closes the window

3楼:

唉,不管是不是WM_CLOSE了,反正一个空的对话框,没有任何控件的情况下,要关闭它就只能点击系统关闭按纽了。我想知道该怎样彻底销毁窗口和窗口对象。

4楼:

CDialog::OnClose()->WM_QUIT->DestroyWindow()->WN_DESTROY->0->close
|
|
|
|
delete this;

5楼:

楼上说的是模式对话框的销毁过程。测试结果是:WM_SYSCOMMOND→OnSysCommond()→WM_CLOSE→OnClose()→DestroyWindow()→WM_DESTORY→OnDestroy()中delete this;

当测试无模式对话框时,我发现OnClose()并没有调用DestroyWindow(),不信你们可以试试的。

MSDN里的说法是:无模式对话框通常由父视图或框架窗口(应用程序的主框架窗口或文档框架窗口)创建和拥有。默认的 OnClose 处理程序调用销毁对话框窗口的 DestroyWindow。如果对话框是独立的,没有任何指针指向它也没有其他特殊的所属权语义,则应重写 PostNcDestroy 以销毁 C++ 对话框对象。还应重写 OnCancel 并从其内部调用 DestroyWindow。如果对话框并不是独立的,则对话框的所有者应在不再需要 C++ 对象时将其销毁。

6楼:

郁闷。VC6,VC7都试过了。
我做了一个摸态对话框A,然后又做了一个非模态的对话框B,我让B作为A的子窗口。当我鼠标点系统菜单的关闭按钮时,用spy++观察消息流,根本就没有WM_DESTROY消息的。MSDN好象在说谎。

当我把B做成模态之后,就能跟踪到WM_DESTROY消息,是窗口销毁过程中的最后一个消息。

跟踪了一下OnClose()的代码,唉,看不懂。

大虾多指点指点吧。。。。。

7楼:

void CSampleDialog : : PostNcDestroy ( )
{
delete this ;
}

8楼:

MSDN中的这句话:"无模式对话框通常由父视图或框架窗口(应用程序的主框架窗口或文档框架窗口)创建和拥有。默认的 OnClose 处理程序调用销毁对话框窗口的 DestroyWindow。",如果有谁能证明它是正确的,我可以送他200分,不食言。

另外各位在讨论问题时,没尝试过的东西,最好不要人云亦云。

9楼:

这里试的时候是调用PostNcDestroy的,不过真的没有调用DestroyWindow,期待高手解答

10楼:

to umbrella1984(雨伞):PostNcDestroy()可以吗?得在WM_NCDESTROY消息处理中调用PostNcDestroy()吧。我测试时,WM_NCDESTROY也没有捕捉到。

11楼:

因为这时候窗口根本就没有销毁,而是隐藏了

12楼:

当我关掉非模式对话框以后调用了对话框的PostNcDestroy函数,我不知道是什么消息或什么函数发起的,当我打开和关闭对话框时在spy里看见了WM_NCACTIVATE和WM_ACTIVATE消息。

13楼:

网上找到的,你看看对你有没有帮助

创建窗体 ...
1.WM_GETMINMAXINFO
2.WM_NCCREATE
3.WM_NCCALCSIZE
4.WM_CREATE
创建完毕.

显示窗体 ...
1.WM_SHOWWINDOW
2.WM_WINDOWPOSCHANGING
3.WM_WINDOWPOSCHANGING
4.WM_ACTIVATEAPP
5.WM_NCACTIVATE
6.WM_GETTEXT
7.WM_ACTIVATE
8.WM_SETFOCUS
9.WM_NCPAINT
10.WM_GETTEXT
11.WM_ERASEBKGND
12.WM_WINDOWPOSCHANGED
13.WM_SIZE
14.WM_MOVE
显示完毕.

更新窗体...
WM_PAINT
更新结束.

//当点击"最小化"......
1.WM_NCLBUTTONDOWN
2.WM_CAPTURECHANGED
3.WM_SYSCOMMAND
4.WM_GETMINMAXINFO
5.WM_GETTEXT
6.WM_WINDOWPOSCHANGING
7.WM_GETMINMAXINFO
8.WM_NCCALCSIZE
9.WM_NCPAINT
10.WM_GETTEXT
11.WM_ERASEBKGND
12.WM_WINDOWPOSCHANGED
13.WM_MOVE
14.WM_SIZE
//点击"最大化"..........
1.WM_NCLBUTTONDOWN
2.WM_CAPTURECHANGED
3.WM_SYSCOMMAND
4.WM_GETTEXT
5.WM_WINDOWPOSCHANGING
6.WM_GETMINMAXINFO
7.WM_NCCALCSIZE
8.WM_NCPAINT
9.WM_GETTEXT
10.WM_ERASEBKGND
11.WM_WINDOWPOSCHANGED
12.WM_MOVE
13.WM_SIZE
//点击“关闭”.......
1.WM_NCLBUTTONDOWN
2.WM_CAPTURECHANGED
3.WM_SYSCOMMAND
4.WM_CLOSE
5.WM_WINDOWPOSCHANGING
6.WM_WINDOWPOSCHANGED
7.WM_NCACTIVATE
8.WM_ACTIVATE
9.WM_ACTIVATEAPP
10.WM_KILLFOCUS
11.WM_DESTROY
12.WM_NCDESTROY

14楼:

PostNcDestroy是一个虚函数,在里面可以放上delete this; 以实现窗口对象的自销毁。
WM_NCDESTROY是窗口被销毁时最后的一个消息,在它的响应函数OnNcDestroy()中调用PostNcDestroy(),如果在MFC中,点击“关闭”并不能产生WM_NCDESTROY消息,那么PostNcDestroy()也没什么意义了。

我用spy++查到的消息流大致如下:
//点击“关闭”.......
1.WM_NCLBUTTONDOWN
2.WM_CAPTURECHANGED
3.WM_SYSCOMMAND
4.WM_CLOSE
5.WM_WINDOWPOSCHANGING
6.WM_WINDOWPOSCHANGED
7.WM_NCACTIVATE
8.WM_ACTIVATE
9.WM_ACTIVATEAPP
10.WM_KILLFOCUS

就缺WM_DESTROY 和WM_NCDESTROY了。实际上只要按照MSDN的说法,MFC的OnClose()确实调用了CWnd::DestroyWindow(),那么就肯定会产生WM_DESTROY 和WM_NCDESTROY消息的。

不想再弄下去了。换个方法做好了,大不了在对话框面板上加个OK按钮,把系统菜单去掉不要了。

15楼:

要想完全销毁一个对话框,就重载对话框的OnOk和OnCancel函数,然后在这两个函数里面调用DestroyWindow,如果你是使用new分配的内存,可以重载PostNcDestroy函数,然后在PostNcDestroy函数里面调用delete this
在默认的情况下,非模态对话框是不会自己调用DestroyWindow来销毁窗口,只是把它隐藏了,你可以在关闭一个非模态对话框后用IsWindow函数来判断这个对话框是否被销毁。
还有,不管对话框里面有没有OK和Cancel按钮,当你按esc,cancel键,系统菜单的关闭时,都会调用OnCancel.而当你点OK键,回车键时,都会调用OnOK

看CSDN别人的讨论是一个很好的学习方式,哈哈!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: