控件提供的方式都是dll形式,dll都是编译好的二进制代码。然而微软也知道我们会有修改控件界面和行为的需求。对于界面的修改,提供了颜色修改技术、用户自绘CustomDraw技术、拥有者自绘OwnerDraw技术。有了这些技术,对于界面上的处理,就差不多了。然而在行为上,却无法修改。所以,系统就提供了窗口子类化技术。我们通常也叫控件子类化技术,因为子类化在控件上使用的最多,本来也是因为这个需求而产生的,同时控件也是窗口哦。
为了让大家轻松明白子类化技术,我绘制了一个原理流程图,如下所示:
【窗口(控件)子类化原理流程示意图】
从图中你可以看到消息队列、消息循环、系统内置的控件窗口过程和我们提供的控件窗口过程四个部分。黑色箭头的黑线表示的流程,是控件的消息处理的默认流程,这个路线可以完成控件的默认的UI和行为。而将控件子类化之后,就将消息处理的默认流程更改了,消息循环之后的消息先流向我们提供的控件窗口过程里处理。我们可以处理我们感兴趣的消息,然后将其他消息交给控件默认的窗口过程处理。当然,如果你要处理所有的消息,也是可以的。这样你就完全控制了一个按钮的UI界面和行为。行为指的是交互方式和功能。子类化的本质其实就是修改窗口类中关联的窗口过程,所以我们使用SetWindowLong来完成窗口过程的修改。我们提供的窗口过程和普通的窗口过程一样,处理消息方式也是一样的。只是对于不想处理的消息,你不再交给DefWindowProc函数处理了,而是调用函数CallWindowProc来调用默认的控件窗口过程,这个默认的窗口过程函数名由SetWindowLong返回。
基本原理的理解和基本的编程模式都讲了,如果你有了整体的认识,那就继续深入学习如何写代码实现。代码实现分析文章,请参考《窗口子类化如何实现切换多个子窗口控件的焦点》和《win32实现鼠标经过控件时的实时提示功能》。