【win32学习】对GetWindowLong(hwnd, 0)和SetWindowLong(hwnd, 0, 0)的学习理解

阅读Windows程序设计第5版中的CHECKER3.c程序时,对于GetWindowLong(hwnd, 0)和SetWindowLong(hwnd, 0, 0)不太理解

CHECKER3部分代码:

           case   WM_CREATE :
                  <span style="color:#ff0000;">SetWindowLong (hwnd, 0, 0) </span>;       // on/off flag
                  return 0 ;
        
           case   WM_LBUTTONDOWN :
                 <span style="color:#ff0000;"> SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;</span>
                  InvalidateRect (hwnd, NULL, FALSE) ;
                return 0 ;

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

                  GetClientRect (hwnd, &rect) ;
                  Rectangle (hdc, 0, 0, rect.right, rect.bottom) ;
     
                  if (<span style="color:#ff0000;">GetWindowLong (hwnd, 0)</span>)
                  {
        <span style="white-space:pre">		</span>//.....
                  }
对于第二个参数为什么为0,网上搜了度娘搜了很多也没有满意答案,后来仔细看MSDN终于理解了,看MSDN关于SetWindowLong说明

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

LONGSetWindowLong(
HWND  hWnd, //handletowindow
int   nlndex, //offsetofvaluetoset
LONG  dwNewLong //newvalue
);

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

nlndex

指定将设定的大于等于0的偏移值。有效值范围从0到额外类的存储空间的字节数减4:例如若指定了12或多于12个字节的额外窗口存储空间,则应设索引位8来访问第三个4字节,同样设置0访问第一个4字节,4访问第二个4字节。要设置其他任何值,可以指定下面值之一:
常量
常量值
意义
GWL_EXSTYLE
-20
设定一个新的扩展 风格
GWL_HINSTANCE
-6
设置一个新的 应用程序实例句柄。
GWL_ID
-12
设置一个新的 窗口 标识符
GWL_STYLE
-16
设定一个新的窗口风格。
GWL_USERDATA
-21
设置与窗口有关的32位值。每个窗口均有一个由创建该窗口的应用程序使用的32位值。
GWL_WNDPROC
-4
为窗口过程设定一个新的地址。
GWL_HWNDPARENT -8 改变子窗口的父窗口,应使用SetParent函数。
当hWnd参数标识了一个对话框时,也可使用下列值:
常量
常量值
意义
DWL_DLGPROC
DWLP_MSGRESULT + sizeof(LRESULT) (值:4)
设置对话框过程的新 地址
DWL_MSGRESULT
0
设置在对话框过程中处理的消息的 返回值
DWL_USER
DWLP_DLGPROC + sizeof(DLGPROC) (值:8)
设置的应用程序私有的新的额外信息,例如一个句柄或 指针
dwNewLong
指定的替换值。
返回值
如果函数成功,返回值是指定的32位整数的原来的值。如果函数失败,返回值为0 。若想获得更多错误信息,请调用GetLastError函数。
如果指定32位整数的原来的值为0,并且函数成功,则返回值为0,但是函数并不清除最后的 错误信息,这就很难判断函数是否成功。这时,就应在调用SetWindowLong之前调用callingSetLastError(0)函数来清除最后的 错误信息。这样,如果函数失败就会返回0,并且 GetLastError。也返回一个非零值。

    度娘找了很多资料都没看明白,其实msdn已经说的很清楚了,只是我第一遍看得不仔细没看懂,SetWindowLong和GetWindowLong其实是操作额外存储空间的值,同时windows也设置了一些负数的宏让这个额外空间具有相应的含义,在CHECKER3程序中用wndclass.cbWndExtra = sizeof(long);指定了额外存储空间为4个字节,第二个参数为0则SetWindowLong将第三个参数的值放入额外空间偏移为0的位置,32位值刚好占据了分配的4个字节,msdn里面说了最大偏移量为额外空间大小减4,所以第二个参数的偏移量最大值为0,如果设置1、2等函数就会返回错误0.

   不过如果你增大额外存储空间大小,就可以增加偏移量的范围,比如wndclass.cbWndExtra = 2*sizeof(long); 则偏移量的范围就可以设置成(0-4)。


SetWindowLong设置值放入偏移处4个字节的存储空间,可以测试一下:

case WM_CREATE :
			SetWindowLong (hwnd, 3, 1) ; // on/off flag
			return 0 ;
//......
case WM_PAINT:
			hdc = BeginPaint(hwnd, &ps);
			offsetValue0 = GetWindowLong(hwnd, 0);  //获取偏移量0的值
			offsetValue1 = GetWindowLong(hwnd, 1);  //获取偏移量1的值
			offsetValue2 = GetWindowLong(hwnd, 2);  //获取偏移量2的值
			offsetValue3 = GetWindowLong(hwnd, 3);  //获取偏移量3的值
			TextOut(hdc, 0, 0, szBuffer, wsprintf(szBuffer, TEXT("%d"), offsetValue0));
			TextOut(hdc, 0, 20, szBuffer, wsprintf(szBuffer, TEXT("%d"), offsetValue1));
			TextOut(hdc, 0, 40, szBuffer, wsprintf(szBuffer, TEXT("%d"), offsetValue2));
			TextOut(hdc, 0, 60, szBuffer, wsprintf(szBuffer, TEXT("%d"), offsetValue3));
			EndPaint(hwnd, &ps);
			return 0;

结果为:16777216

     65536

     256

     1

SetWindowLong(hwnd, 3, 1)将偏移量3的空间设置为1,即是将额外存储空间第24位设置为1,相对于偏移量0的位置是第24位,相对偏移量1的位置是第16位,相对于偏移量2的位置是第8位,所以用GetWindowLong获得以上结果。


  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值