说说安全子类

原创 2005年05月27日 14:30:00

作者:袁晓辉    文章来源:www.farproc.com   更新时间:2005-5-25

说说安全子类

说起“窗口子类化”(Subclass Window),估计大家都不陌生吧?不就是SetWindowLong (hwnd, GWL_WNDPROC, NewProc)嘛,如果还有什么要说的话,那就是为了兼容3264Windows,换用SetWindowLongPtr吧。就这么简单吗?其实越是看起来简单的东西,往往越容易被误用,我们来看一个例子:

 

 

这看似没有问题的代码真的可靠吗?未必!!

想想吧,如果在我们做“... 一些操作 ...”的时候,又有一个程序子类了该窗口(hwnd)会怎么样?那个子类会用它的procedure替换我们的NewWndProc,并保存我们的NewWndProc指针。这时windows消息会先经过它的procedure,到我们的NewWndProc,然后我们传递给OldWndProc。当我们替换回原来的窗口过程时发生了好么?我们恢复了OldWndProcwindows消息直接传递给了OldProc,而不会经过后来的那个子类的procedure了,我们一下子取消了两个子类!一个是我们添加的,一个是在我们之后添加的。如果后来的那个子类的procedure在堆上分配了内存,准备在收到WM_DESTROY时释放,那么它永远都收不到这个消息,这块内存也就泄漏了……

不要以为子类的添加和删除是一个“入栈、出栈”的操作(你只能操作栈顶也就是最后入栈的元素)。如果你想要删除你的子类,而你窗口procedure并没有位于子类链的最顶端的话,你就不能安全地删除你的子类。如果你在这时移除了你的子类并恢复了你所保存的旧prodecure的话,那么在你后面添加的子类都被你从子类链上“摘掉”了。安全的做法是你必须等待,直到可以安全删除你的子类时再删除,并且在等待期间把收到的任何消息传递给前一个procedure处理。

这是很令人讨厌的,所以,微软为我们准备了好用的函数来帮我们完成这些操作。用SetWindowsSubclass(位于Windows XP自带的CommCtl32.dll 6.0版中。 后面的几个函数也一样) 可以很方便地添加一个子类,它会在内部保存前一个子类的必要信息,传递你指定的“参考数据”到子类的procedure。用DefSubclassProc 传递消息到前一个子类。完成操作时,用RemoveWindowSubclass 删除你添加的子类本身,这个函数会自动做好所有的处理,你不必担心你的procedure是否位于子类链的顶端。但是有一点同样需要注意,你必须在被窗口(hwnd)销毁前删除你的子类。

 

 

微软为我们提供的这中“安全”子类的机制非常棒,目前用的人却不是很多,可能是因为它只能在XP系统上用的缘故吧。但不管如何,我们还是关心一下新技术的好,说不定哪天能用得着。

 

 参看这里:子类化控件的新方法

 参看这里:子类化控件的新方法

 

注:本文部分内容参考这里

简单实现Cglib子类代理

  • 2017年01月21日 11:55
  • 452KB
  • 下载

使用Java Mail Authenticator子类进行用户认证来发送电子邮件示例

/** * CrazyItTest * 使用JavaMail的Authenticator类进行用户认证发送带附件的电子邮件示例 */ package com.labci.javamail...
  • tujiyue
  • tujiyue
  • 2011年05月26日 22:17
  • 6781

PyGridTableBase的子类

  • 2012年08月20日 15:25
  • 4KB
  • 下载

java继承实质、父类引用指向子类对象(多态)、声明时类型、运行时类型

继承是面向对象的三大特征(封装、继承和多态)之一,也是java语言的重要特性。 那么,继承父类的成员变量和继承父类的方法有什么区别吗?答案是肯定的。有的人甚至都不知道这个问题的存在。 继承成员变量...

asp+access实现无限子类功能

  • 2010年03月08日 17:43
  • 24KB
  • 下载

黑马程序员_JAVA学习日记_JAVA中API:集合框架1(Collection,List,Set及其子类和迭代器的应用)

黑马程序员-学习日记   黑马程序员_JAVA中集合框架1(Collection,List,Set及其子类和迭代器的应用)   ------- android培训、java培训、期待与您交流!...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:说说安全子类
举报原因:
原因补充:

(最多只允许输入30个字)