深刻解析C++的WNDCLASS構造體及其在Windows中的運用。本站提示廣大學習愛好者:(深刻解析C++的WNDCLASS構造體及其在Windows中的運用)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析C++的WNDCLASS構造體及其在Windows中的運用正文
WNDCLASS是一個由體系支撐的構造,用來貯存某一類窗口的信息,如ClassStyle,新聞處置函數,Icon,Cursor,配景Brush等。也就是說,CreateWindow只是將某個WNDCLASS界說的窗體釀成實例。要獲得某一窗口的WNDCLASS數據,可以用GetClassLong();
RegisterClass()就是在體系注冊某一類型的窗體。也就是將你供給的WNDCLASS數據注冊為一個窗口類,在WNDCLASS.lpszClassName中界說該WNDCLASS的標識,不管CreateWindow或CreateWindowEx創立的窗口都必需對應一個WNDCLASS,但一個WNDCLASS可以有多個窗口對象。
有一些體系預界說的窗口類,如:ClassName=_T("BUTTON" or "COMBOBOX" or "EDIT" or "LISTBOX" or "MDICLIENT" or "SCOLLBAR" or "STATIC"),要用這些窗體,直接用CreateWindow創立響應對象就是了。要獲得某一窗口的窗口類,可以用GetClassName();
WNDCLASS中的回調函數是窗體的新聞處置函數:CALLBACK WinProc(MESSAGE msg,LPARAM lparam,WPARAM wParam);
窗口類屬性界說
構造WNDCLASS包括一個窗口類的全體信息,也是Windows編程中應用的根本數據構造之一,運用法式經由過程界說一個窗口類肯定窗口的屬性,界說以下:
typedef struct _WNDCLASS { UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; } WNDCLASS, *PWNDCLASS;
舉例解釋
例子:
long CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//聲明 //WinMain函數是一切Windows運用法式的進口,相似c說話中的main函數其功效是完成//一系列的界說和初始化,並發生新聞輪回。函數解釋: int WINAPI WinMain(HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow // show state ) { //初始化,初始化包含窗口類的界說、注冊、創立窗話柄例和顯示窗口四部門 HWND hwnd; MSG Msg; WNDCLASS wndclass; char lpszClassName[]="窗口"; //窗口類名 char lpszTitle[]="測試窗口"; //窗口題目名 //窗口類界說,窗口類界說了窗口的情勢與功效,窗口類界說經由過程給窗口類數據構造WNDCLASS賦值完成 //該數據構造中包括窗口類的各類屬性 wndclass.style =0; // 窗口類型為缺省類型CS_ Class Style 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=lpszClassName; //窗口類名為“窗口” //以下是窗口類的注冊-----------Windows體系自己供給部門預界說的窗口類,法式員也能夠自界說窗口類,窗口類必需先注冊後應用。 if(!RegisterClass(&wndclass)) //假如注冊掉敗 收回正告 {MessageBeep(0); return FALSE;} //創立窗口創立一個窗口的實例由函數CreateWindow()完成 hwnd=CreateWindow( lpszClassName, //窗口類名,創立窗口時必定要基於我們曾經注冊過的窗口類名,即"窗口"。 lpszTitle, //窗口題目名 WS_OVERLAPPEDWINDOW, //窗口的作風 WS_ Windows Style CW_USEDEFAULT, //窗口左上角坐標值為缺省值 CW_ Create Wndow CW_USEDEFAULT, CW_USEDEFAULT, //窗口的高和寬為缺省值 CW_USEDEFAULT, NULL, //此窗口無父窗口 NULL, //此窗口無子菜單 hInstance, //創立此窗口的運用法式確當前句柄 NULL //不應用該值 ); //顯示窗口 ShowWindow(hwnd,nCmdShow); //繪制用戶區 UpdateWindow(hwnd); //新聞輪回 while(GetMessage(&Msg,NULL,0,0)) //GetMessage()函數是從挪用線程的新聞隊列中掏出一條新聞;關於每個運用法式窗口線程,操作體系都邑為其樹立一個新聞隊列,當我們的窗口有新聞時(即一切與這個窗口線程相干的新聞),把持體系會把這個新聞放到該線程的新聞隊列傍邊,我們的窗口法式就經由過程這個GetMessage()函數從本身的新聞隊列中掏出一條一條詳細的新聞並停止呼應操作。 { TranslateMessage(&Msg);//對"新聞對"的轉化,如對鍵盤的WM_KEYDOWN和WM_KEYUP新聞對轉化為WM_CHAR新聞,而且將轉換後的新新聞送達到我們的新聞隊列中去,這個轉化操作不會影響本來的新聞,只會發生一個新的新聞。 DispatchMessage(&Msg);//DispatchMessage()函數是將我們掏出的新聞傳到窗口的回調函數行止理;可以懂得為該函數將掏出的新聞路由給操作體系,然後操作體系去挪用我們的窗口回調函數對這個新聞停止處置。 } return Msg.wParam; //新聞輪回停止 即法式停止時 將信息前往體系 } //窗口函數,窗口函數界說了運用法式對吸收到的分歧新聞的呼應,個中包括了運用法式對各類能夠接收到的新聞的處置進程,時新聞處置分支掌握語句的聚集 long CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_DESTROY: PostQuitMessage(0); default: //缺省時采取體系新聞缺省處置函數 return DefWindowProc(hwnd,message,wParam,lParam); } return (0); }
注:窗口回調函數的函數指針界說typedef LRESULT CALLBACK (* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
WNDPROC OldWndProc; LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (Msg) { ...... } return CallWindowProc(OldWndProc,g_Wnd,Msg,wParam,lParam); } OldWndProc = (WNDPROC)GetWindowLong(g_Wnd,GWL_WNDPROC); SetWindowLong(hwnd, GWL_WNDPROC,(LPARAM)(WNDPROC)NewWndProc);
經由過程挪用SetWindowLong函數可以修正該窗體類的回調函數。
CallBack 函數中的wParam和lParam有甚麼差別:
WPARAM wParam, 界說成WORD型
LPARAM lParam 界說成LONG型
在Win 3.x中,WPARAM是16位的,而LPARAM是32位的,二者有顯著的差別。
在Win32 API中,WPARAM和LPARAM都是32位,所以沒有甚麼實質的差別。
然則習氣上,我們情願應用LPARAM傳遞地址,而WPARAM傳遞其他參數。
function MouseHookProc(nCode: Integer; wPar: WPARAM; lPar: LPARAM): lResult; stdcall;
假如我要斷定鼠標左鍵能否按下,用wParam==WM_LBUTTONDOWN斷定.
lParam 是 (tagMOUSEHOOKSTRUCT的指針)PMouseHookStruct類型,重要是取得發送窗口句柄,鼠標坐標 ,和其他一些信息 。
lParam 用的時刻須要強迫轉換,轉換成PMouseHookStruct類型.
PMouseHookStruct = ^TMouseHookStruct; tagMOUSEHOOKSTRUCT = packed record pt: TPoint; hwnd: HWND; wHitTestCode: UINT; dwExtraInfo: DWORD; end; TMouseHookStruct = tagMOUSEHOOKSTRUCT;例如:
function GetMsgProc(nCode: Integer; wPara: WPARAM; lPara: LPARAM) : lResult; stdcall; var hGetMsgHook:HHOOK; Msg: TMsg; begin if (nCode >= 0) then begin FillChar(pMsgData^, Sizeof(TMessageRecord), #0); Msg := TMsg(Pointer(lPara)^); end; Result := CallNextHookEx(hGetMsgHook, nCode, wPara, lPara); end;
數據構造原型
typedef struct _WNDCLASS{ UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HANDLE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; }WNDCLASS;
構造解釋
WNDCLASS 構造包括了RegisterClass函數注冊的類屬性
重量簡介
style: 指定類作風。這些作風可經由過程按位或操作組合起來。作風以下:
cbClsExtra: 指定緊隨在 WNDCLASS 數據構造後分派的字節數。體系將其初始化為零。
cbWndExtra: 指定緊隨在窗話柄例以後分派的字節數,體系將其初始化為零。假如運用法式正在用WNDCLASS構造注冊一個在RC資本描寫文件頂用CLASS指令創立的對話框時,它必需設置這個字段為 DLGWINDOWEXTRA。
hInstance: 標識了該窗口類的窗口進程地點的模塊實例的句柄,不克不及為NULL。
hIcon: 標識了該窗口類的圖標。hIcon字段必需是一個圖標的句柄;若hIcon字段為NULL,則不管什麼時候用戶把運用法式縮至最小時,運用法式必需畫一個圖標。
hCursor: 標識該窗口類的光標,hCursor必需是一個光標資本的句柄。若hCursor字段為NULL,則不管什麼時候鼠標移到運用法式窗口時,運用法式必需顯式設置光標外形。
hbrBackground: 標識了該窗口類的配景畫筆。hbrBackground字段必需是用於繪制配景的物理刷子的句柄,或許是一個色彩的值。假如給出一個色彩的值,它必需是上面列出的尺度體系色彩之一(體系將對所選色彩加1)。假如給出了色彩值,它必需是轉換成以下的HBRUSH類型之一的色彩:
lpszMenuName:指向NULL停止的字符串,該字符串描寫菜單的資本名,好像在資本文件裡顯示的名字一樣。若應用一個整數標識菜單,可使用MAKEINTRESOURCE宏。假如lpszMenuName為NULL,
那末該窗口類的窗口將沒有默許菜單。
lpszClassName:指向NULL停止的字符串,或許是一個原型(atom)。若該參數是一個原型,它必需是一個有先前挪用RegisterClass或許 RegisterClassEx函數發生的類原型。類原型必需作為lpszClassName的低字,高字必需為0.若lpszClassName是一個字符串,它描寫了窗口類名。這個類名可所以由RegisterClass或許RegisterClassEx注冊的名字,或許是任何預界說的控件類名。
構造信息Header 在winuser.h聲明,包括windows.h