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

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

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,且第二个滚动条没有画出来呢????

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章