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,且第二個滾動條沒有畫出來呢????

 

 

 

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