汇编教程之窗口子类化

在这一讲,我们将学习什么是窗口子类化和怎样按你所想要的方式方便地使用它。

理论:

如果你曾经在 Windows 环境下编过程序,有时候就会发现:有一个现成的窗口,几乎有你所需要的全部功能,但还不完全一样(否则就没有必要讲这一节了)。你曾遇到过这样的处境吗,如果你需要一个具有过滤特殊字符功能的 Edit 控件。当然最直接的方法就是自己用代码来实现,但这的确是一个费时又很困难的任务,而窗口子类化就可以用来做这种事情。

窗口子类化允许你接管被子类化的窗口,使你对它有绝对的控制权。举个例子了来阐明一下:例如你需要一个只接受十六进制数字输入的文本编辑框,如果使用一个简单的 Edit控件,当用户输入十六进制以外的字符时,你既不知道也无计可施。也就是说,当用户进文本框中输入字符串 "zb+q*" 时,如果除了拒绝接受整个字符串以外几乎什么也不能做,至少这显得特别不专业。重要的是,你需要具有输入检测的能力,即每当用户输入一个字符到编辑框中时要能检测这个字符。

现在来解释实现细节:当用户往文本框中输入字符时,Windows 会给Edit控件的窗口函数发送 WM_CHAR 消息。这个窗口函数本身寄生于 Windows 中,因此不能直接修改它。但是我们可以重定向这个消息使之发送到我们自己编写的窗口处理函数。如果自定义窗口要处理这个消息那就可以处理它,如果不处理就可以把这个消息转发到它原来窗口处理函数。通过这种方式,自定义的窗口处理函数就把它自己插入到 Windows 系统和 Edit 控件之间。

看下面的流程:

窗口子类化之前

Windows ==>Edit 控件的窗口处理函数。

子类化之后

Windows ==>自定义的窗口处理函数==> Edit 控件的窗口处理函数。

注意子类化并不局限于控件,可以子类化任何窗口,现在我们要把精力集中到怎样实现子类化一个窗口上。让我们想想Windows 怎样知道 Edit 控件的窗口处理函数放在什么地方。猜的?…肯定不是。原来 WNDCLASSEX 结构的成员 lpfnWndProc 指出了窗口函数地址。如果能用自己编写的窗口函数的地址来替换这个成员变量,那 Windows 不就把消息发到自定义的窗口函数了吗! 我们通过调用函数SetWindowLong 来实现这个任务,此函数的原型为:

SetWindowLong PROTO hWnd:DWORD, nIndex:DWORD, dwNewLong:DWORD

hWnd = 将要实施子类化的窗口的句柄

nIndex = 函数了功能索引

GWL_EXSTYLE 设置窗口的扩展风格.

GWL_STYLE 设置新的窗口风格

GWL_WNDPROC 设置新的窗口处理函数地址

GWL_HINSTANCE 设置新的应用程序句柄

GWL_ID 设置新的窗口标识

GWL_USERDATA 设置一个与这个窗口相关的给用户使用的32位的数据

dwNewLong = 用来更新的数据

我们的工作还是比较简单的:

写一个窗口函数用于处理发给 Edit 控件的消息。

用参数GWL_WNDPROC调用SetWindowLong 函数,如果调用成功那么返回值就是与调用功能相联系的一个32位的整数

在我们的程序中,返回值就是原先窗口函数的地址。我们要保存这个值以便以后使用。 记住:有一些我们不处理的消息,需要把它们派遣给原来的窗口函数来处理,这就用到另外一个函数 CallWindowProc, 函数原型为:

CallWindowProc PROTO lpPrevWndFunc:DWORD, hWnd:DWORD, Msg:DWORD, wParam:DWORD, lParam:DWORD

lpPrevWndFunc = 窗口原来函数的地址. 剩下的四个参数就是发给自定义函数的参数,直接把它们传给函数 CallWindowProc 就行了。

时间: 2024-10-31 10:48:35

汇编教程之窗口子类化的相关文章

利用窗口子类化隐藏系统图标

窗口子类化是一种非常有用的技术,通常它用在Windows GUI编程方面,我们用这种技术来创建新的控件,比如让SubClassing一个Edit控件添加一些消息处理让它变成MaskEdit控件等等.反过来想想如果我们SubClassing一个有ES_PASSWORD风格的窗口控件,得到它的密码是难是吗?很简单,不过是一句CallWindowProc调用,只不过在NT等系统上需要Inject一个DLL到目标进程来SubClassing一个进程中的窗口或是子窗口. 用Spy++看了一下,资源管理器里

窗口子类化-实例应用

所谓窗口子类化:改变一个已经存在的窗口实例的性质:消息处理与其他实例属性.   通常在SDK中所谓的窗口子类化就是改变一个窗口函数(如GetWindowLong()和SetWindowLong())通过这两个函数来设置窗口的属性等:   而今天我们主要内容是介绍MFC中的子类化,它跟SDK中的子类化不太一样: 所有MFC窗口有相同的窗口函数,由该窗口函数根据窗口句柄查找窗口实例,在把消息映射到该窗口类(class)得消息处理函数上.为了利用MFC的消息映射机制,不宜改变窗口函数(名),MFC也把

解说Win32的窗口子类化

也许你需要一个特殊的Edit来限制浮点数的输入,但是现有的Edit却并不能完成这项工作--因为它只能够单纯的限制大小写或者纯数字.当你在论坛上求救的时候,某个网友告诉你:"用子类化."你也许会在看到一线曙光的同时多出了一连串的问题:何为子类化?子类化的原理是什么?如何实现子类化?下面就让我从一个简单的C++程序开始,一步步解开你的疑团吧. 首先,我为你列出以下这个C++程序: #include <iostream> using namespace std; class Pa

子类化

子类化 如果你曾经在 Windows 环境下编过程序,有时候就会发现:有一个现成的窗口,几乎有你所需要的全部功能,但还不完全一样.如果你需要一个具有过滤特殊字符功能的 Edit 控件.当然最直接的方法就是自己用代码来实现,但这的确是一个费时又很困难的任务,而子类化就可以用来做这种事情. 子类化允许你接管被子类化的窗口,使你对它有绝对的控制权.举个例子了来阐明一下:例如你需要一个只接受十六进制数字输入的文本编辑框,如果使用一个简单的 Edit控件,当用户输入十六进制以外的字符时,你既不知道也无计可

自绘控件的子类化方法

  1.       新建一个基于对话框的MFC程序. 2.       在工程中添加一个新类CMyButton,基类选择CButton. 3.       然后转至新生成的MyButton.h头文件中,将鼠标放在类名CMyButton上点击一下,打开"属性"窗口,在"消息"按钮下为此类添加 WM_LBUTTONDOWN,WM_LBUTTONUP消息,并重写DrawItem虚函数(这个函数是重绘按钮时要调用的,在这里面可以自定义一些绘制按钮的操作,必须设置控件属性为

C++ 中超类化和子类化及他们的区别

C++ 中超类化和子类化 超类化和子类化没有具体的代码,其实是一种编程技巧,在MFC和WTL中可以有不同的实现方法. 窗口子类化: 原理就是改变一个已创建窗口类的窗口过程函数.通过截获已创建窗口的消息,从而实现监视或修改已创建窗口类的行为属性.可以用来改变或者扩展一个已存在的窗口的行为,而不用重新开发.比如要获得那些预定义控件窗口类(按钮控件.编辑控件.列表控件.下 拉列表控件.静态控件和滚动条控件)的功能而又要修改它们的某些行为. 子类化的优点主要体现在以下两个方面:首先,它不需要创建新的窗口

眼见为实(2):介绍Windows的窗口、消息、子类化和超类化

眼见为实(2):介绍Windows的窗口.消息.子类化和超类化 这篇文章本来只是想介绍一下子类化和超类化这两个比较"生僻"的名词.为了叙述的完整性而讨论了Windows的窗口和消息,也简要讨论了进程和线程.子类化(Subclassing)和超类化(Superclassing)是伴随Windows窗口机制而产生的两个复用代码的方法.不要把"子类化.超类化"与面向对象语言中的派生类.基类混淆起来."子类化.超类化"中的"类"是指W

汇编教程之超类化

在这一讲我们将学习什么是超类化以及它有什么作用:同时你还会学到怎样在自己的窗口中用Tab键在控件中切换这一技巧. 理论: 在你的程序生涯中你肯定遇到过这样的情况,你需要一系列的控件,但它们之间却只有一点点的不同.例如,你可能需要10个只接受数字的 Edit 控件,当然你可以通过多种方法来达到这个目的. 创建自己的类并用它实例化为那些控件 创建那些 Edit 控件并把它们全部子类化 超类化Edit 控件 第一种方法太乏味了,因为你必须自己实现Edit 控件的每个功能,但这项工作不是轻松就能完成的.

窗口的子类化与超类化

1. 子类化 改变一个已经存在的窗口实例的性质:消息处理与其他实例属性.在SDK编程范畴内,子类化就是改变一个窗口实例的窗口函数(通过GetWindowLong()和SetWindowLong()),子类化所要做的就是为某窗口实例编写新的窗口函数.其操作是在实例级别上进行的.在MFC中子类化的情况有所不同:所有MFC窗口有相同的窗口函数,由该窗口函数根据窗口句柄查找窗口实例,在把消息映射到该窗口类(class)得消息处理函数上.为了利用MFC的消息映射机制,不宜改变窗口函数(名),MFC也把子类