一、什么是子类化(Subclass)
视窗系统是基于消息驱动的。因此每一个窗口都有一个函数来处理这些消息,系统管理的窗口结构中有一域记录着这个函数的地址(使用GetWindowLong函数传入索引标识GWL_WNDPROC可获取此值)。所有系统发送到这个窗口的消息都会交由此函数来处理。所以改变窗口结构中这个指针值到自定义的某个函数(使用SetWindowLong函数带GWL_WNDPROC索引标识修改此值),就能接管窗口绝大部分的消息。实际中我们只处理自己感兴趣的某些消息,之后可以有选择的继续Call原来那个窗口函数(使用CallWindowProc函数调用)或直接返回一个值。
二、实现子类化的一般方法
从上面可以看出,子类化主要使用几个API函数,这几乎是所有实现子类化相同的方法。相关API说明如下:
1 、 WINUSERAPI LONG WINAPI GetWindowLongA(HWND hWnd, int nIndex);
WINUSERAPI LONG WINAPI GetWindowLongW(HWND hWnd, int nIndex);
2 、 SetWindowLong 与 CallWindowProc 函数这不再列出来了,都是粉容易的!
使用 ComCtl32.dll version 6 实现窗口子类化
Windows XP 带的ComCtl32.dll version 6 提供了4个可以让创建子类化更简单,并且可以消除前面提到的缺陷的函数。这些新的函数封装了对多组参考数据(multiple sets of reference data)的管理操作,使得开发者能将精力集中到具体的程序特性而不是对子类的管理上。这些新的函数为:
SetWindowSubclass
GetWindowSubclass
RemoveWindowSubclass
DefSubclassProc
下面是对这些函数的描述。
SetWindowSubclass
这个函数用来子类化一个窗口。每个子类可以用p pfnSubclass 和 uIdSubclass (SetWindowSubclass的参数)唯一标识。多个子类可以共享同一个子类过程,而用标识(ID)来区分。改变参考数据可以提供再一次调用SetWindowSubclass 来实现。一个重要的优点是每一个子类实例可以拥有自己的参考数据。
子类过程的声明和传统的窗口过程有点细微的差别,它多了两个参数:子类ID和参考数据。参看下面这个函数声明的最后两个参数:
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass,
DWORD_PTR dwRefData);
每次新的窗口过程收到一个消息时,它同时得到了一个子类ID和参考数据。
注意:所有作为参数传递给该函数的字符串均为Unicode,不管有没有定义Unicode编译选项。
GetWindowSubclass
该函数取回一个子类的信息。比如你可以用
窗口子类化(SubClassing) SetWindowLong
最新推荐文章于 2021-12-15 21:55:53 发布
本文详细介绍了窗口子类化(Subclassing)的概念,通过SetWindowLong函数来替换窗口的默认消息处理函数,以及如何使用ComCtl32.dll version 6中的新函数SetWindowSubclass来简化子类化操作。文章还探讨了跨进程子类化的挑战,包括使用HOOK技术实现在不同进程间的消息拦截,并提供了相应的DLL代码示例。
摘要由CSDN通过智能技术生成