SetWindowLong和SetClassLongh函数关于索引GWL_WNDPROC,GCL_WNDPROC的区别

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

个人看法,如有雷同,纯属巧合!!!

SetWindowLong:The SetWindowLong function changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory。

大意是说该函数改变指定窗口的属性,也可以设置窗口额外内存中的值。

索引包含:GWL_STYLE,GWL_WNDPROC,GWL_ID,GWL_HINSTANCE,GWL_UERDATA

 

SetClassLong:The SetClassLong function replaces the specified 32-bit (long) value at the specified offset into the extra class memory or the WNDCLASSEX structure for the class to which the specified window belongs.

大意是说该函数替换在额外类存储空间的指定偏移地址的32位长整型值,或替换指定窗口所属类的WNDCLASSEX结构。

索引包含:GCL_HBRBACKGROUND,GCL_HICON,GCL_HCURSOR,GCL_MENUNAME,GCL_WNDPROC

 

下面说说主题了:从函数的表面意思就可以知道,SetWidnowLong是用于窗口的,SetClassLong是用于类的。一个窗口是根据一个固定的类建立的,SetWindowLong改变窗口的窗口函数只是用于这一个窗口,SetClassLong改变类的窗口函数,也就是说自此以后用该类创建的窗口的窗口函数都改变了。

msdn:

GWL_WNDPROCG, Sets a new address for the window procedure.

GCL_WNDPROC  ,  Replaces the address of the window procedure associated with the class.

下面是实验验证:

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK ScrollProc (HWND, UINT, WPARAM, LPARAM) ;
WNDPROC OldProc[2];
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPreInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Test") ;

HWND hwnd ;

MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra= 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName= szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox ( NULL, TEXT ("This program requires Windows NT!"),szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow( szAppName, // window class name
TEXT ("The Test Program"), // window caption
WS_OVERLAPPEDWINDOW , // window style
CW_USEDEFAULT,// initial x position
CW_USEDEFAULT,// initial y position
CW_USEDEFAULT,// initial x size
CW_USEDEFAULT,// initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters

 

ShowWindow (hwnd, SW_SHOWNORMAL) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hwndscrollbar[2];
static int cxChar,cyChar;
int i;
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;

switch (message)
{
case WM_CREATE:
cxChar=LOWORD(GetDialogBaseUnits());
cyChar=HIWORD(GetDialogBaseUnits());

hwndscrollbar[0]=CreateWindow(TEXT("scrollbar"),NULL,SBS_VERT | WS_CHILD |WS_VISIBLE,0,0,0,0,
         hwnd,(HMENU) 0,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);

OldProc[0]=SetWindowLong(hwndscrollbar[0],GWL_WNDPROC,ScrollProc);
hwndscrollbar[1]=CreateWindow(TEXT("scrollbar"),NULL,SBS_VERT | WS_CHILD |WS_VISIBLE,0,0,0,0,
         hwnd,(HMENU) 1,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
OldProc[1]=GetClassLong(hwndscrollbar[1],GCL_WNDPROC);
if(OldProc[0]==OldProc[1])
   SetClassLong(hwnd,GCL_HBRBACKGROUND,(LONG)CreateSolidBrush(RGB(255,0,0)));
else
{if(OldProc[1]==0)
   SetClassLong(hwnd,GCL_HBRBACKGROUND,(LONG)CreateSolidBrush(RGB(0,255,0)));
else
   SetClassLong(hwnd,GCL_HBRBACKGROUND,(LONG)CreateSolidBrush(RGB(0,0,255)));
}
InvalidateRect(hwnd,NULL,TRUE);
return 0 ;

case WM_SIZE:
 MoveWindow(hwndscrollbar[0],5*cxChar,5*cyChar,4*cxChar,5*cyChar,TRUE);
    MoveWindow(hwndscrollbar[1],12*cxChar,5*cyChar,4*cxChar,5*cyChar,TRUE);
 return 0;

case WM_PAINT:
hdc=BeginPaint (hwnd, &ps) ;

EndPaint (hwnd, &ps) ;
return 0 ;

case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}


LRESULT CALLBACK ScrollProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int id=GetWindowLong(hwnd,GWL_ID);
 return CallWindowProc(OldProc[id],hwnd,message,wParam,lParam);
}

 

此时得到的背景色为红色,且两个滚动条都画出来了,这也就是说SetWindowLong函数没有影响该类的窗口函数。

 

当把SetWindowLong改成SetClassLong ,GWL_WNDPROC改成GCL_WNDPROC,得到的背景色为绿色,且第二个滚动条没有画出来。这说明SetClassLong的确影响了类scrollbar的窗口函数,但为什么会变成0,且第二个滚动条没有画出来呢????

 

 

 

Cocos2d-x windows編譯 出現GWL_WNDPROCGWL_USERDATA未定义 指定生成的平臺win32 以及指定Visual Studio的版本。 阅读详情

相关推荐

GWL_WNDPROCGWL_USERDATA、GWL_HINSTANCE未定义

注:如果编译不过改为win32。

qq_54125940的博客 1656

SetWindowLongSetWindowPos函数详解

一个应用程序可以一个系统美为于类,但是不能以一个其他进程产生的窗口类为子类,SetwindowLong函数通过改变与一个特殊的窗口类相联系的窗口过程来创建窗口子类,从而使系统调用新的窗口过程而不是以前定义的窗口过程。Windows CE:如果这是一个可见的顶层窗口,并且未指定SWP_NOACTIVATE标志,则这个函数将激活窗口、如果这是当前的激活窗口,并且指定了SWP_NOACTIVATE或SWP_HIDEWINDOW标志,则激活另外一个可见的顶层窗口。SWP_NOACTIVATE:不激活窗口。

m0_37346206的博客 4389

error C2065: “GWL_WNDPROC”: 未声明的标识符

endif。

本博客仅供免费阅读,不提供咨询服务。请勿私信。 1213

SetWindowLong设置窗口新过程

函数原型:LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong); 主要说明函数的第二个参数为GWL_WNDPROC的情况。 GWL_WNDPROC Sets a new address for the window procedure. You cannot change this attribute ...

weixin_34292287的博客 1435

一种注入进程,获得完全操控的方法之二

作 者: menting时 间: 2007-12-12,16:50链 接: http://bbs.pediy.com/showthread.php?t=56442看到了我的之一,我想大家会很清楚,因为这个方法的最大的BUG就是在回调函数之后来处理,如果前面已经处理了,那么我们就无法处理了。而且又要修改系统DLL,比较不完美。我最近又发现了两种方法:  一、修改RegisterClassA:  相对

1084

Windows API函数SetWindowLong

SetWindowLong()用于改变一个窗口的属性。 LONG SetWindowLong( HWND hWnd, //handle to window(窗口句柄) int nlndex, //offset of value to set(改变窗口上的何种属性) LONG dwNewLong // new value(指定该属性为一个新的具体样式) ); 窗口属性包括窗口的样式(GWL_STYLE)、扩展...

zxf347085420的博客 4095

32位程序64位编译时提示 GWL_WNDPROC 未定义,GWL_USERDATA未定义

&lt;WinUser.h&gt; 中: /* * Window field offsets for GetWindowLong() */ #define GWL_WNDPROC (-4) ... #ifdef _WIN64 #undef GWL_WNDPROC #undef GWL_HINSTANCE #undef GWL_HWNDPARENT #undef GWL_...

iMatt的专栏 1万+

Linux 常用基本命令及常用技巧

用户有时的程序有可能要花费很多时间,如果将它放在前台运行,将导致无法继续做其 他事情,最好的方法就是将它放在后台运行,甚至可能希望在用户注销系统后,程序还可以。如果不需要使用光盘或软盘,则需先执行卸载命令之后,才能将光盘或软盘退出。文件,则系统会不间断地询问,以确认您的确要删除目录或文件。可利用任务调度命令,指定系统定期在某个时间运行这些程序,轻轻松松完成想要执行的工。注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达。命令可以关闭所有程序, 依照用户的需要, 重新启动或关机。

AI论道的博客 1万+

窗口子类化(SubClassing) SetWindowLong

一、什么是子类化(Subclass) 视窗系统是基于消息驱动的。因此每一个窗口都有一个函数来处理这些消息,系统管理的窗口结构中有一域记录着这个函数的地址(使用GetWindowLong函数传入索引标识GWL_WNDPROC可获取此值)。所有系统发送到这个窗口的消息都会交由此函数来处理。所以改变窗口结构中这个指针值到自定义的某个函数(使用SetWindowLong函数GWL_WN

靠别人不如靠自已。 5562

SetClassLong

SetClassLong   函数功能:该函数替换在额外类存储空间的指定偏移地址的32位长整型值,或替换指定窗口所属类的WNDCLASSEX结构。  函数原型:DWORD SetClassLong(HWND hWnd,int nlndex,LONG dwNewLong);  参数:  hWnd:窗口句柄及间接给出的窗口所属的类。  nlndex:指定

laurensky的专栏 1411

Win32 API 列表5 (格式有点乱)

西安邮电学院 徐兆元1201 SetBoundsRect 控制相邻矩形重叠  Yes Yes Yes1202 SetBrushOrgEx 设置当前刷子的起点  No Yes Yes1203 SetCapture 设置鼠标捕获 "    函数功能:该函数在属于当前线程的指定窗口里设置鼠标捕获。一旦窗口捕获了鼠标,所有鼠标输入都针对该窗口,无论光标是否在窗口的边界内。同一时刻只能有一个窗口捕获鼠标

FLxyzsby的专栏 1万+

C++的回调函数

回调函数主要在“回”字,正常的函数调用方式不太一样。正常的函数由开发者自己定义返回类型以及传入的参数,并且也是由开发者自己调用,而回调函数功能其实也是由开发者自己实现,但是返回类型以及入参则由注册回调的函数来决定(若是自己编写则可以自定义注册函数,由他人提供则只能根据接口实现),而且调用方也不是开发者,而是注册方决定。整个过程也就是一个“回”字,开发者将自己的函数指针交给对方,这是“去”,而对方则在适当的时候调用这个函数,也可以将一些开发者需要的数据传回来,这便是来回了。

QtCompany的博客 572

标识符”wndproc_cocos2d-x 4.x 项目创建 & 如果报错GWL_WNDPROC的解决方法

前言:windows下面如何创建cocos2d-x4.0项目,以及遇到下面错误的解决方法:#错误 C2065 “GWL_WNDPROC”: 未声明的标识符 #错误 C2065 “GWL_WNDPROC”: 未声明的标识符 #错误 C2065 “GWL_USERDATA”: 未声明的标识符 #错误 C2065 “GWL_WNDPROC”: 未声明的标识符正式开始,总共两步:一、安装CMake:CMa...

weixin_39907220的博客 668

MFC 窗体样式修改

窗体创建之后,如何设置窗体的样式呢? 一般情况下使用GetWindowLongW与SetWindowLongW即可实现窗体样式的修改或者使用ModifyStyle。 关于MFC存在GetWindowLongWGetWindowLongA使用哪一个,可以通过 IsWindowUnicode(this-&gt;m_hWnd)获取是使用哪一类型,true则使用GetWindowLongW反之使用G...

weixin_34149796的博客 411

Windows API 函数: SetClassLong

<br />Windows API 函数: SetClassLong<br /> SetClassLong  常用于替换光标样式,增添美观性;DWORD SetClassLong(<br /><br />    HWND hWnd,  // handle of window (窗口句柄)<br />    int nIndex,  // index of value to change (设置的属性)<br />    LONG dwNewLong   // new value (设置的属性的值)<br /

jphaoren的专栏 3531

6.3 创建窗口

创建窗口

qq_36314864的博客 780
下一篇: 【转帖】关于GlobalAlloc,GlobalLock,GlobalUnLock的理解
coolmousewife
博客等级 码龄18年 6粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值