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

时间:2021-07-28 17:04:13

在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 - 有上下文帮助按钮  */