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

来源:互联网 发布:淘宝卖充值卡进货渠道 编辑:程序博客网 时间:2024/04/30 19:00

阅读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 flagreturn 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获得以上结果。


0 0
原创粉丝点击