阅读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
常量
| 常量值 |
意义
|
---|---|---|
GWL_EXSTYLE
| -20 |
设定一个新的扩展
风格。
|
GWL_HINSTANCE
| -6 |
设置一个新的
应用程序实例句柄。
|
GWL_ID
| -12 | |
GWL_STYLE
| -16 |
设定一个新的窗口风格。
|
GWL_USERDATA
| -21 |
设置与窗口有关的32位值。每个窗口均有一个由创建该窗口的应用程序使用的32位值。
|
GWL_WNDPROC
| -4 |
为窗口过程设定一个新的地址。
|
GWL_HWNDPARENT | -8 | 改变子窗口的父窗口,应使用SetParent函数。 |
常量
| 常量值 |
意义
|
---|---|---|
DWL_DLGPROC
| DWLP_MSGRESULT + sizeof(LRESULT) (值:4) |
设置对话框过程的新
地址。
|
DWL_MSGRESULT
| 0 |
设置在对话框过程中处理的消息的
返回值。
|
DWL_USER
| DWLP_DLGPROC + sizeof(DLGPROC) (值:8) |
设置的应用程序私有的新的额外信息,例如一个句柄或
指针。
|
度娘找了很多资料都没看明白,其实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获得以上结果。