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

详见帖子: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别人的讨论是一个很好的学习方式,哈哈!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值