C++ 中超类化和子类化常用API

在windows平台上,使用C++实现子类化和超类化常用的API并不多,由于这些API函数的详解和使用方法,网上一大把。本文仅作为笔记,简单的记录一下。

子类化:SetWindowLong,GetWindowLong,CallWindowProc,FindWindowEx

超类化:GetClassInfoEx,RegisterClassEx,UnRegisterClass

以上函数在代码中的使用见《C++ 中超类化和子类化

VC中基于SDK编程的窗口子类化

VC中基于SDK编程的窗口子类化的基本步骤如下:

(1)正常创建原始窗口,得到窗口的句柄。

(2)调用GetWindowLong得到原来的窗口函数OldWndProc。

(3)调用SetWindowLong设置新的窗口函数NewWndProc。

(4)在窗口函数NewWndProc中使用CallWindowProc将消息发到原来的窗口函数OldWndProc。

SetWindowLong
函数功能:该函数改变指定窗口的属性.函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。

函数原型:LONG
SetWindowLong(HWND hWnd,int nlndex,LONG dwNewLong);

参数:

hWnd:窗口句柄及间接给出的窗口所属的类。

nlndex:指定将设定的大于等于0的偏移值。有效值的范围从0到额外类的存储空间的字节数-4:例如若指定了12位或多于12位的额外类存储空间,则应设为第三个32位整数的索引位8。要设置其他任何值,可以指定下面值之一:

GWL_EXSTYLE:设定一个新的扩展风格。GWL_STYLE:设定一个新的窗口风格。

GWL_WNDPROC:为窗口过程设定一个新的地址。GWL_ID:设置一个新的窗口标识符。

GWL_HINSTANCE:设置一个新的应用程序事例句柄。

GWL_USERDATA:设置与窗口有关的32位值。每一个窗口均有一个由创建该窗口的应用程序使用的32位值。

GWL_ID 设置一个新的窗口标识符。

当hWnd参数标识了一个对话框时,也可使用下列值:

DWL_DLGPROC:设置对话框过程的新地址。

DWL_MSGRESULT:设置在对话框过程中处理的消息的返回值。

DWL_USER:设置的应用程序私有的新的额外信息,例如一个句柄或指针。

dwNewLong:指定的替换值。

返回值:如果函数成功,返回值是指定的32位整数的原来的值。如果函数失败,返回值为0。若想获得更多错误信息,请调用GetLastError函数。

备注:如果由hWnd参数指定的窗口与调用线程不属于同一进程,将导致SetWindowLong函数失败。

如果使用带GWL_WNDPROC索引值的SetWindowLong函数替换窗口过程,则该窗口过程必须与WindowProccallback函数说明部分指定的指导行一致。 
如果使用带
DWL_MSGRESULT索引值的SetWindowLong函数来设置由一个对话框过程处理的消息的返回值,应在此后立即返回TRUE。否则,如果又
调用了其他函数而使对话框过程接收到一个窗口消息,则嵌套的窗口消息可能改写使用DWL_MSGRESULT设定的返回值。

通过使用函数RegisterClassEx将结构WNDCLASSEX中的cbWndExtra单元指定为一个非0值来保留新外窗口内存。

不能通过调用带GWL_HWNDPARENT索引值的SetWindowLong的函数来改变子窗口的父窗口,应使用SetParent函数。

GetWindowLong 

函数功能:该函数获得有关指定窗口的信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值。

函数原型:LONG
GetWindowLong(HWND hWnd,int nlndex);

参数:

hWnd:窗口句柄及间接给出的窗口所属的窗口类。

nlndex:指定要检索的基于0的的偏移量。有效值的范围从0到窗口额外内存空间的字节数,最小为4。例如,若指定了12位或多于12位的窗体类的额外存储空间,则应设为第三个32位整数的索引位8。要获得任意其他值,指定下列值之一:

GWL_EXSTYLE;获得扩展窗口风格。

GWL_STYLE:获得窗口风格。

GWL_WNDPROC:获得窗口过程的地址,或代表窗口过程的地址的句柄。必须使用GWL_WNDPROC函数调用窗口过程。

GWL_HINSTANCE:获得应用事例的句柄。

GWL_HWNDPAAENT:如果父窗口存在,获得父窗口句柄。

GWL_ID:获得窗口标识。

GWL_USERDATA:获得与窗口有关的32位值。每一个窗口均有一个由创建该窗口的应用程序使用的32位值。

在hWnd参数标识了一个对话框时也可用下列值:

DWL_DLGPROC:获得对话框过程的地址,或一个代表对话框过程的地址的句柄。必须使用函数CallWindowProc来调用对话框过程。

DWL_MSGRESULT:获得在对话框过程中一个消息处理的返回值。

DWL_USER:获得应用程序私有的额外信息,例如一个句柄或指针。

返回值:如果函数成功,返回值是所需的32位值;如果函数失败,返回值是0。若想获得更多错误信息请调用
GetLastError函数。

备注:通过使用函数RegisterClassEx将结构WNDCLASSEX中的cbWndExtra单元指定为一个非0值来保留额外类的存储空间。

CallWindowProc

函数功能:将指定消息信息传送给指定的窗口过程. lpPrevWndFunc是窗口消息处理函数指针(函数名), hWnd为接受窗体句柄.

函数原型:LRESULT CallWindowProc(WNDPROC lpPrevWndFunc,HWND hWnd.UINT Msg,WPARAM wParam,LPARAMIParam);

参数:

lpPrevWndFunc:参数主要是指向你要调用的函数句柄

hWnd:指向接收消息的窗口过程的句柄。

Msg:指定消息类型。

wParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。

IParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。

返回值:返回值指定了消息处理结果,它与发送的消息有关。

备注:使用函数CallWindowsProc可进行窗口子类化。子类是一个窗口或者相同类的一套窗口,在其消息被传送到该类的窗口过程之前,这些消息是由另一个窗口过程进行解释和处理的。

FindWindowEx

函数功能:该函数获得一个窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数查找子窗口,从排在给定的子窗口后面的下一个子窗口开始。在查找时不区分大小写。

函数原型:HWND FindWindowEx(HWND hwndParent,HWND hwndChildAfter,LPCTSTR lpszClass,LPCTSTR lpszWindow);

参数:

hwndParent:要查找子窗口的父窗口句柄。

如果hwnjParent为NULL,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口。

Windows NT5.0 and later:如果hwndParent是HWND_MESSAGE,函数仅查找所有消息窗口。

hwndChildAfter :子窗口句柄。查找从在Z序中的下一个子窗口开始。子窗口必须为hwndPareRt窗口的直接子窗口而非后代窗口。如果HwndChildAfter为 NULL,查找从hwndParent的第一个子窗口开始。如果hwndParent 和 hwndChildAfter同时为NULL,则函数查找所有的顶层窗口及消息窗口。

lpszClass:指向一个指定了类名的 空结束字符串,或一个标识类名字符串的成员的指针。如果该参数为一个成员,则它必须为前次调用theGlobaIAddAtom函数产生的全局成员。该成 员为16位,必须位于lpClassName的低16位,高位必须为0。

lpszWindow:指向一个指定了窗口名(窗口标题)的空结束字符串。如果该参数为 NULL,则为所有窗口全匹配。返回值:如果函数成功,返回值为具有指定类名和窗口名的窗口句柄。如果函数失败,返回值为NULL。

VC中超类化常用API

窗口超类化是在窗口类——WNDCLASS或WNDCLASSEX(非MFC类概念)级别进行的改变窗口类特征的。改变已有窗口类的行为属性。

GetClassInfoEx

函数功能:  获取进程中窗体类信息

函数原型:BOOL GetClassInfo(HINSTANCE
hInstance,   LPCTSTR
lpClassName, LPWNDCLASS
lpWndClass);

参数:

hInstance:应用程序实例;
lpClassName :窗口类名;               
lpWndClass :用于接收类名的结构体变量  ;

返回值:如果函数成功,返回值为非零;

备注:在超类化中,取得想要进行超类化操作的窗口类的信息

RegisterClassEx

函数功能:注册一个窗体类,以便通用CreateWindowEx, CreateWindow来实例化一个窗体。

函数原型:RegisterClassEx(CONST WNDCLASSEX *lpwcx );

参数:

Ipwcx:指向一个WNDCLASSEX结构的指针。在传递给这个函数之前,必须在结构内填充适当的类的属性。

返回值:如果函数成功,返回这个窗口类型的标识号;如果函数失败,返回值为0。

UnRegisterClass

函数功能:该函数删除一个窗口类,清空该类所需的内存。

函数原型:BOOL UnRegisterClass(LPCTSTR IpClassName; HINSTANCE hlnstance);

参数:

IpClassName:指向一个空结束字符串的指针,或是一个整型原子。如果IpClassName是一个字符串,则它指定了窗口类的类名。这个类名必须由此前调用RegisterClassEx函数来注册。系统类,如对话框控制,必须被注册。

如果这个参数是一个整型原子,它必须是由此前调用GlobalAdd原子函数创建的全局原子。这个16位整型数小于OxCOOO,必须是lpszClass的低16位,其高位宇必须为0。

hlnstance:创建类的模块的事例句柄。

返回值:如果函数成功,返回值为非零;如果未发现类或由此类创建的窗口仍然存在,则返回值为0。

若想获得更多错误信息,请调用GetLastError函数。

备注:在调用这个函数之前,应用程序必须销毁由指定类创建的所有窗口。应用程序注册的所有窗口类在应用程序中止后都为未注册的类。

/* 附窗口样式参考列表: 

WS_POPUP - 弹出式窗口(不能与WS_CHILDWINDOW样式同时使用) 

WS_CHILDWINDOW - 子窗口(不能与WS_POPUP合用) 

WS_MINIMIZE - 最小化状态 

WS_VISIBLE - 可见状态 

WS_DISABLED - 不可用状态 

WS_CLIPSIBLINGS - 使窗口排除子窗口之间的相对区域 

WS_CLIPCHILDREN - 当在父窗口内绘图时,排除子窗口区域 

WS_MAXIMIZE - 具有最大化按钮,须指定WS_SYSTEM样式 

WS_CAPTION - 有标题框和边框(和WS_TILED样式相同) 窗口带有一个标题栏,经测试,实际上等于 (WS_BORDER Or WS_DLGFRAME) 

WS_BORDER - 有单边框 窗口带有一个薄边框 

WS_DLGFRAME - 带对话框边框样式,不带标题框 带有一般对话框的风格,但没有标题栏 

WS_VSCROLL - 有垂直滚动条 窗口带有一个垂直滚动条 

WS_HSCROLL - 有水平滚动条 窗口带有一个水平滚动条 

WS_SYSMENU - 标题框上带有窗口菜单(须指定WS_CAPTION样式) 在窗口的标题栏上增加一个系统菜单,该窗口必须具有 WS_CAPTION 风格(即WS_BORDER和WS_DLGFRAME) 

WS_SIZEBOX 和 WS_THICKFRAME - 有可调边框(与WS_SIZEBOX样式相同) 窗口带有一个可以调整窗口大小的边框(即VB里的Sizable,其他地方的边框均指不具调整大小功能的边框) 

WS_GROUP - 组样式,每个组的第一个控件具有WS_TABSTOP样式 

WS_TABSTOP - 可接受TAB键焦点 

WS_MINIMIZEBOX - 有最小化按钮 窗口带有最小化按钮,该窗口必须具有 WS_CAPTION 风格 

WS_MAXIMIZEBOX - 有最大化按钮 窗口带有最大化按钮,该窗口必须具有 WS_CAPTION 风格 

WS_OVERLAPPEDWINDOW 和 WS_TILEDWINDOW:- 具有层叠,标题框,系统菜单,可调边框,系统按钮   窗口是一个交迭式窗口,并且组合了 WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU,

WS_THICKFRAME, WS_MINIMIZEBOX 以及 WS_MAXIMIZEBOX 这些风格 

WS_POPUPWINDOW - 具有单边框,弹出式,系统菜单样式

WS_OVERLAPPED 和 WS_TILED:窗口是一个交迭式窗口。交迭式窗口带有一个标题栏和一个边框 

*/  

/* 窗口扩展样式参考列表: 

WS_EX_DLGMODALFRAME - 带双层边框 

WS_EX_NOPARENTNOTIFY - 创建/销毁时不通知父窗口 

WS_EX_TOPMOST - 窗口置顶(停留在所有非最高层窗口的上面) 

WS_EX_ACCEPTFILES - 可接受文件拖放 

WS_EX_TRANSPARENT - 透明样式,在同属窗口已重画时该窗口才可重画 

WS_EX_MDICHILD - MDI子窗口样式 

WS_EX_TOOLWINDOW - 工具条窗口样式 

WS_EX_WINDOWEDGE - 带凸起边缘的边框 

WS_EX_CLIENTEDGE - 带阴影的边缘 

WS_EX_CONTEXTHELP - 有上下文帮助样式,标题栏包含一个问号标志 

WS_EX_RIGHT - 右对齐 

WS_EX_RTLREADING - 窗口文本从右到左显示 

WS_EX_LEFTSCROLLBAR - 垂直滚动条在窗口左边界 

WS_EX_CONTROLPARENT - 允许用户使用TAB键在窗口的子窗口间搜索 

WS_EX_STATICEDGE - 当窗口为不可用状态时创建一个三维边缘 

WS_EX_APPWINDOW - 当窗口可见时将一个顶层窗口放置在任务栏上 

WS_EX_OVERLAPPEDWINDOW - 带凸起边缘的边框,边缘有阴影 

WS_EX_PALETTEWINDOW - 带立体边框,有工具条窗口样式,窗口在顶层 

WS_EX_LAYERED - 分层或透明窗口,该样式可使用混合特效 

WS_EX_NOINHERITLAYOUT - 子控件不继承窗体或控件的布局 

WS_EX_LAYOUTRTL - 窗体或控件将具有从右向左的布局(因而会被镜像) 

WS_EX_COMPOSITED - 用双缓冲从下到上绘制窗口的所有子孙(WinXP以上) 

WS_EX_NOACTIVATE - 处于顶层但不激活 

*/  

/* 控件样式参考列表:  

DS_ABSALIGN - 对话框的坐标为屏幕坐标(缺省为客户区坐标)  

DS_SYSMODAL - 系统模式(仅支持16位程序),不能与DS_CONTROL同用  

DS_LOCALEDIT - 在对话框内部为编辑框分配内存(仅支持16位程序)  

DS_SETFONT - 可定制对话框字体  

DS_MODALFRAME - 框架样式(不能与WS_CAPTION同用)  

DS_NOIDLEMSG - 无空闲消息  

DS_SETFOREGROUND - 使对话框在最前面显示  

DS_3DLOOK - 四周有3维边框  

DS_FIXEDSYS - 使用系统固定字体  

DS_NOFAILCREATE - 忽略创建过程中的错误  

DS_CONTROL - 控件模式,可作为其他对话框的子窗口  

DS_CENTER - 在屏幕居中  

DS_CENTERMOUSE - 在鼠标位置居中  

DS_CONTEXTHELP - 有上下文帮助按钮  */
时间: 2024-10-14 08:56:26

C++ 中超类化和子类化常用API的相关文章

C++ 中超类化和子类化

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

Win32中安全的子类化(翻译)

关于子类化的话题虽然有些旧,但它至今仍然不失为一种开发Windows的强有力技术,在MFC的内核.甚至.NET的内核中都离不开它,希望本连载能对Windows开发的爱好者有所帮助. 原文标题:Safe Subclassing in Win32作者:Kyle MarshMSDN技术组 点击此处查看原文 摘要 本文描述了Win32环境下的子类化,描述了它是如何工作的以及实现安全的子类化必须要遵循的规则.本文涵盖了实例子类化和全局子类化.而超类化则作为一个全局子类化的可选替代方案被介绍.从Win16到

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

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

窗口的子类化与超类化

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

子类化和超类化区别(介绍Windows的窗口、消息、子类化和超类化)(转)

原文地址:http://maqianli210.blog.sohu.com/75497589.html 这篇文章本来只是想介绍一下子类化和超类化这两个比较“生僻”的名词.为了叙述的完整性而讨论了Windows的窗口和消息,也简要讨论了进程和线程.子类化(Subclassing)和超类化(Superclassing)是伴随Windows窗口机制而产生的两个复用代码的方法.不要把“子类化.超类化”与面向对象语言中的派生类.基类混淆起来.“子类化.超类化”中的“类”是指Windows的窗口类. 0 运

窗口的子类化与超类化——子类化是窗口实例级别的,超类化是在窗口类(WNDCLASS)级别的

1. 子类化 理论:子类化是这样一种技术,它允许一个应用程序截获发往另一个窗口的消息.一个应用程序通过截获属于另一个窗口的消息,从而实现增加.监视或者修改那个窗口的缺省行为.子类化是用来改变或者扩展一个已存在的窗口的行为.而不用重新开发的有效途径.想要获得那些预定义控件窗口类(按钮控件.编辑控件.列表控件.下拉列表控件.静态控件和滚动条控件)的功能而又要修改它们的某些行为的一个便利的方法就是对它们进行子类化.例如,对于一个在对话框中的多行编辑框来说,当用户按下Enter键时,对话框会关闭.通过对

窗口 超类化 子类化 HOOK

body { font-family: Bitstream Vera Sans Mono; font-size: 11pt; line-height: 1.5; } html, body { color: #000000; background-color: #C2E7C7; } h1 { font-size:1.5em; font-weight:bold; } h2 { font-size:1.4em; font-weight:bold; } h3 { font-size:1.3em; fon

流畅python学习笔记:第十二章:子类化内置类型

子类化内置类型 在python2.2之后,内置类型都可以子类化,但是有一个注意事项:内置类型不会调用用户定义的类覆盖的特殊方法.这个说起来比较绕口,什么意思呢.我们来看下下面的代码: class DopperDict(dict):     def __setitem__(self, key, value):         super(DopperDict,self).__setitem__(key,[value]*2) ⑴ if __name__=="__main__":     d

MFC学习笔记之12:用窗口过程WH_CALLWNDPROC钩子+子类化实现皮肤功能

实现方法: 1.定义自己的控件类,比如CButtonEx:public CButton,实现自绘. 2.安装WH_CALLWNDPROC钩子 a.定义HHOOK全局变量 HHOOK g_WndProcHook=NULL; b.在CXXAPP ::InitInstance()中安装钩子 g_WndProcHook=SetWindowsHookEx( WH_CALLWNDPROC, (HOOKPROC)CallWndProc, NULL, GetCurrentThreadId()); c.在CXXA