CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  界面

[请教]关于非摸态对话框的销毁问题

楼主caesar22(背后的小刀)2005-05-22 01:15:42 在 VC/MFC / 界面 提问

我见N多资料都在强调非模态对话框只能在堆上分配空间,这个我明白。它们又强调要调用调用DestroyWindow()以达到彻底销毁自身对象的作用,因为DestroyWindow()的调用会引起OnDestroy()的调用,在OnDestroy函数中delete   this。  
   
  说的都很有道理。但是他们都不约而同的把DestroyWindow()函数的调用位置塞进了OnOk()和OnCancel()中了。  
   
  我的问题:假如一个对话框,空空的,没有OK也没有Cancel,只有标题栏上有个"关闭"的系统按钮,现在我该怎么销毁new的非模态对话框呢???地球人都知道系统按钮"关闭",对应的消息是WM_CLOSE,在OnClose的消息处理函数中,会继续调用CDialog::OnClose,一直都没调用DestroyWindow()哎,delete   this应该放在哪里?????????  
  问题点数:50、回复次数:22Top

1 楼horisly(SUN YAT-SEN UNIVERSITY (逸仙先生))回复于 2005-05-22 01:51:18 得分 4

球人都知道系统按钮"关闭",对应的消息是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    
  Top

2 楼caesar22(背后的小刀)回复于 2005-05-22 03:29:30 得分 0

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

3 楼umbrella1984(雨伞(KEN))回复于 2005-05-22 03:58:45 得分 3

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

4 楼caesar22(背后的小刀)回复于 2005-05-22 09:07:18 得分 0

楼上说的是模式对话框的销毁过程。测试结果是:WM_SYSCOMMOND→OnSysCommond()→WM_CLOSE→OnClose()→DestroyWindow()→WM_DESTORY→OnDestroy()中delete   this;  
   
  当测试无模式对话框时,我发现OnClose()并没有调用DestroyWindow(),不信你们可以试试的。  
   
  MSDN里的说法是:无模式对话框通常由父视图或框架窗口(应用程序的主框架窗口或文档框架窗口)创建和拥有。默认的   OnClose   处理程序调用销毁对话框窗口的   DestroyWindow。如果对话框是独立的,没有任何指针指向它也没有其他特殊的所属权语义,则应重写   PostNcDestroy   以销毁   C++   对话框对象。还应重写   OnCancel   并从其内部调用   DestroyWindow。如果对话框并不是独立的,则对话框的所有者应在不再需要   C++   对象时将其销毁。  
   
  Top

5 楼zuoluoyun()回复于 2005-05-22 11:33:39 得分 1

楼上说得对,msdn对这个问题进行了说明的Top

6 楼caesar22(背后的小刀)回复于 2005-05-22 11:38:08 得分 0

郁闷。VC6,VC7都试过了。  
  我做了一个摸态对话框A,然后又做了一个非模态的对话框B,我让B作为A的子窗口。当我鼠标点系统菜单的关闭按钮时,用spy++观察消息流,根本就没有WM_DESTROY消息的。MSDN好象在说谎。  
   
  当我把B做成模态之后,就能跟踪到WM_DESTROY消息,是窗口销毁过程中的最后一个消息。  
   
  跟踪了一下OnClose()的代码,唉,看不懂。  
   
  大虾多指点指点吧。。。。。Top

7 楼zkk520777(维特)回复于 2005-05-22 12:49:13 得分 4

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

8 楼caesar22(背后的小刀)回复于 2005-05-22 13:20:31 得分 0

MSDN中的这句话:"无模式对话框通常由父视图或框架窗口(应用程序的主框架窗口或文档框架窗口)创建和拥有。默认的   OnClose   处理程序调用销毁对话框窗口的   DestroyWindow。",如果有谁能证明它是正确的,我可以送他200分,不食言。  
   
  另外各位在讨论问题时,没尝试过的东西,最好不要人云亦云。Top

9 楼umbrella1984(雨伞(KEN))回复于 2005-05-22 16:15:23 得分 3

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

10 楼caesar22(背后的小刀)回复于 2005-05-22 17:19:54 得分 0

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

11 楼zuoluoyun()回复于 2005-05-22 17:29:36 得分 3

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

12 楼umbrella1984(雨伞(KEN))回复于 2005-05-22 17:39:51 得分 4

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

13 楼umbrella1984(雨伞(KEN))回复于 2005-05-22 17:42:06 得分 5

网上找到的,你看看对你有没有帮助  
   
  创建窗体   ...  
  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    
  Top

14 楼AntonlioX(做人要厚道)回复于 2005-05-22 17:44:18 得分 0

markTop

15 楼caesar22(背后的小刀)回复于 2005-05-22 17:54:17 得分 0

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按钮,把系统菜单去掉不要了。  
   
  Top

16 楼umbrella1984(雨伞(KEN))回复于 2005-05-22 17:58:11 得分 3

可是我的对话框关闭时确实调用了PostNcDestroy函数,当然只是关闭对话框,应用程序没关。Top

17 楼caesar22(背后的小刀)回复于 2005-05-22 17:59:44 得分 0

能把你的程序发过来,我看看吗???  
  wenziking@sina.comTop

18 楼zuoluoyun()回复于 2005-05-22 20:01:28 得分 15

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

19 楼umbrella1984(雨伞(KEN))回复于 2005-05-22 20:34:50 得分 0

to:   caesar22(背后的小刀)    
   
  有没有MSN或QQ?我传给你.Top

20 楼cadinfo(无语清风)回复于 2005-05-22 20:39:16 得分 5

都回答的不错,应该在WM_NCDESTROY中删除吧Top

21 楼caesar22(背后的小刀)回复于 2005-05-22 20:51:35 得分 0

明白了。   zuoluoyun()说的对。MSDN关于这个问题说的太"言赅意简"了.  
  多谢了,也多谢诸多兄弟的讨论。揭贴。散分。Top

22 楼AntonlioX(做人要厚道)回复于 2005-05-22 22:11:43 得分 0

upTop

相关问题

  • 如何销毁非模态的对话框呀!
  • 如何销毁对话框?
  • 急,为什么我不能销毁创建的非模态对话框?
  • 用mfc如何创建一个非摸态对话框~?
  • 各位,关于非摸态对话框的问题。
  • 请问如何使非摸态对话框居中显示
  • 创建另一个对话框的同时销毁本对话框,怎么做?
  • 动态生成对话框
  • 保存对话框状态
  • 无模态对话框

关键词

  • c++
  • 函数
  • 消息
  • 框架
  • 系统
  • 应用程序
  • 对话框
  • 调用
  • wm
  • 销毁

得分解答快速导航

  • 帖主:caesar22
  • horisly
  • umbrella1984
  • zuoluoyun
  • zkk520777
  • umbrella1984
  • zuoluoyun
  • umbrella1984
  • umbrella1984
  • umbrella1984
  • zuoluoyun
  • cadinfo

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo