WIN32學習——Windows訊息機制(一)
1、Win32視窗程式採用的是事件驅動方式執行,也就是訊息機制,當系統通知視窗工作時,就是採用訊息的方式派發給視窗,通過呼叫視窗處理函式進行對訊息對處理。
2、訊息MessageBox結構體:
int MessageBox(
HWND hWnd, //父視窗控制代碼
LPCTSTR lpText, //顯示在訊息框中的文字
LPCTSTR lpCaption, //顯示在標題欄中的文字
UINT uType //訊息框中的按鈕、圖示顯示型別
); //返回點選的按鈕ID
3、每一個視窗都有視窗處理函式,例如:
LRESULT CALLBACK WindowProc(
HWND hwnd, //視窗控制代碼
UINT uMsg, //訊息ID
WPARAM wParam, //訊息引數
LPARAM lParam //訊息引數
);
當系統通知視窗時,會呼叫視窗處理函式同時,會將訊息ID和訊息引數傳遞給視窗處理函式,在視窗處理函式中,沒有手動處理的訊息會使用預設的視窗處理函式DefWindowProc()。
4、訊息相關函式:
GetMessage();
TranslateMessage();
DispatchMessage();
5、常見訊息:
WM_DESTROY:視窗被銷燬時的訊息,無訊息引數(wParam、lParam),常用於在視窗被銷燬之前,做相應的善後處理,例如資源、記憶體等
WM_SYSCOMMAND:系統命令訊息,當點選視窗的最大化、最小化、關閉等命令時,收到這個訊息。常用在視窗關閉時,提示使用者處理。
WM_CREATE:在視窗建立成功還未顯示之前,收到這個訊息。常用於初始化視窗的引數、資源等,包括子視窗的建立。
WM_SIZE:在視窗大小發生變化後,會收到這個訊息。常用於視窗大小變化後,調節視窗內各個部分的佈局。其中,該訊息的附加資料:WPARAM表示視窗大小變化的原因,LPARAM表示變化後窗口客戶區大小,通過呼叫LOWORD獲取變化後寬度,HIWORD獲取變化後高度。
WM_QUIT:用於結束訊息迴圈處理。
WM_PAINT:繪圖訊息。
另外還有鍵盤訊息、滑鼠訊息、定時器訊息等,以後研究。
附練習程式碼:
/*
功能:在點選關閉視窗按鈕時,提示是否關閉視窗,YES關閉視窗,NO取消關閉視窗 WM_SYSCOMMAND: WM_CREATE: WM_SIZE: 以上訊息的使用 */ #include <Windows.h> HINSTANCE g_hInstance; HWND childWnd; void OnCreate(HWND hParent) { childWnd = CreateWindowEx(0,__TEXT("edit"),NULL,WS_CHILD | WS_VISIBLE | WS_BORDER,0,0,100,100,hParent,NULL,g_hInstance,NULL); } void OnSize(HWND hWnd,LPARAM lParam) { int nWidth = LOWORD(lParam); int nHight = HIWORD(lParam); MoveWindow(childWnd,0,0,nWidth,nHight,TRUE); } //視窗處理函式 LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { switch(uMsg) { /* case WM_DESTROY: PostQuitMessage(0); break; */ case WM_SIZE: OnSize(hWnd,lParam); break; case WM_CREATE: OnCreate(hWnd); break; case WM_SYSCOMMAND: if (SC_CLOSE == wParam) { if(IDYES == MessageBox(hWnd,__TEXT("確定是否關閉視窗"),__TEXT("提示"),MB_YESNO)) { PostQuitMessage(0); } //不加else處理,程式會執行DefWindowProc,視窗程序不能關閉 else return 0; }
break; } return DefWindowProc(hWnd,uMsg,wParam,lParam); } //註冊視窗類 BOOL Register(LPCWSTR className) { WNDCLASSEX wc = {0}; wc.cbClsExtra = 0; wc.cbSize = sizeof(WNDCLASSEX); wc.cbWndExtra = 0; wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.hCursor = NULL; wc.hIcon = NULL; wc.hIconSm = NULL; wc.hInstance = g_hInstance; wc.lpfnWndProc = WinProc; wc.lpszClassName = className; wc.lpszMenuName = NULL; wc.style = CS_HREDRAW | CS_VREDRAW; return RegisterClassEx(&wc); } //建立視窗 HWND CreateWin(LPCWSTR className,LPCWSTR winName) { return CreateWindowEx(0,className,winName,WS_OVERLAPPEDWINDOW,100,100,600,600,NULL,NULL,g_hInstance,NULL); } //顯示和更新視窗 void ShowWin(HWND hWnd) { ShowWindow(hWnd,SW_SHOW); UpdateWindow(hWnd); } //訊息迴圈 void Message() { MSG ms = {0}; while (GetMessage(&ms,NULL,0,0)) { TranslateMessage(&ms); DispatchMessage(&ms); } } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) { g_hInstance = hInstance; Register(__TEXT("Main")); HWND hWnd = CreateWin(__TEXT("Main"),__TEXT("This is test")); ShowWin(hWnd); Message(); return 0; }