个人看法,如有雷同,纯属巧合!!!
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,且第二个滚动条没有画出来呢????