彩票走势图

VC++中MFC窗口对象的清除

转帖|其它|编辑:郝浩|2008-09-23 14:31:32.000|阅读 1460 次

概述:VC++中MFC窗口对象的清除

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

  对于vc++初学者来说,总觉得窗口对象的清除过程有些莫名其妙。在程序中看不到对delete的显式调用,这似乎违反了c++中有关初始化和清除的规则。那么,程序是怎样取消一个窗口对象?

  要消除窗口对象,必须清楚窗口对象的构成。在一个通常的程序中,先创建c++窗口对象,然后由Windows创建实际的窗口结构,并返回句柄与c++对象连接。也就是说,窗口对象包含c++窗口对象和Windows窗口对象,两者通过句柄HWND联系。

  现在,让我们看看"正规"的窗口对象清除流程。所谓对象的清除是指释放对象所占的资源,窗口对象中Windows窗口对象占有的是系统资源,c++对象占有的是内存资源。释放系统资源相对要简单一些:调用虚函数DestroyWindow删除Windows窗口对象。如果DestroyWindow删除的是父窗口,Windows会自动为子窗口调用DestroyWindow。一般来说,程序不必调用DestroyWindow。因为当用户关闭窗口时,Windows便发送WM_CLOSE消息,WM_CLOSE的缺省消息处理函数CWnd::OnClose调用DestroyWindow。

  到这时,清除工作已经完成了一半,屏幕上的窗口已经不见了!但是别忘了,在内存中还有一个c++窗口对象。让我们再看看c++对象清除的过程:当窗口被取消时,窗口最后发送的一个消息是WM_NCDESTROY。它缺省的消息处理函数CWnd::OnNcDestroy把c++窗口对象与句柄HWND分离,并调用一个很重要的虚函数PostNcDestroy。这个函数是搞清窗口对象清除的关键。Cwnd中的PostNcDestroy什么都不做。有些MFC窗口类会重载它,并加入delete this代码删除c++对象。这些窗口类常常是以new操作符建立在堆中的。由于重载了PostNcDestroy,使窗口有自动清除功能。因此,我们不用关心清除问题了。另外的一些MFC窗口类一般是以变量形式创建的,MFC没有为也没必要为它们重载PostNcDestroy函数。

  不具备自动清除功能的窗口类,一般在堆栈中创建或嵌入于其它c++对象中:

  • 所有标准的Windows控件类(如CStatic, CEdit, CListBox等等)
  • 由CWnd类直接派生出来的子窗口对象(如用户定制的控件)
  • 拆分窗口类(CSplitterWnd)
  • 缺省的控制条类(CControlBar的派生类)
  • 对话框类(CDialog)在堆栈上创建的模态对话框类
  • 所有的Windows通用对话框(除CFindReplaceDialog)
  • 由ClassWizard创建的对话框
  • 具有自动清除功能的窗口类,一般在堆中创建:
  • 主框架窗口类(直接或间接从CFrameWnd类派生)
  • 视图类(直接或间接从CView类派生)

  从某种程度上来说,MFC的"服务到家"使初学者有些找不着北。不过,不得不承认:MFC干的很漂亮!

  谈到这里,我们应该明白c++里一条重要的准则:用DestroyWindow清除窗口对象,不要用"delete"。

  对于不具备自动清除功能的窗口类使用"delete"时,"delete"先调用析构函数里的DestroyWindow,由于在析构函数中,虚机制不起作用,这里只能调用本地版本(Cwnd类)DestroyWindow函数,显然这不是我们想要的。对于有自动清除功能的窗口类,好象问题更严重一点,前面提到了重载的PostNcDestroy已经含有了"delete this",这样c++对象就被释放了两次。

  很多人认为,vc++同vb一样,是一个完全可视化的产品,不用在看c++的书了。通过上面对窗口对象的清除的介绍,可以发现,Windows程序是与Windows紧密结合的,而且牵涉到很多c++的知识(如虚函数、析构函数、new操作符等)。要对vc++有进一步理解,必须理解Windows机制,深入学习c++。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:开发者在线

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP