你多少歲不重要,看起來像幾歲才重要,不要把辛苦和怨氣都掛在臉上,你想要最好的生活,就先讓生活看到最好的你。。。。
---- 網易雲熱評
一、程式執行機制
1、過程驅動 - 程式的執行過程是按照預定好的順序執行。
2、事件驅動 - 程式的執行是無序,使用者可以根據需要隨機觸發相應的事件。
3、Win32視窗程式就是採用 事件驅動 方式執行,也就是 訊息機制。
4、當系統通知視窗工作時,就採用訊息的方式派發給視窗。
二、訊息組成(windows平臺下)
視窗控制代碼
訊息ID 0-1023
訊息的兩個引數(兩個附帶資訊)
訊息產生的時間
訊息產生時的滑鼠位置
三、視窗處理函式和訊息
1、每個視窗都必須具有視窗處理函式。
LRESULT CALLBACK WindowProc( HWND hwnd, //視窗控制代碼 UINT uMsg, //訊息ID WPARAM wParam, //訊息引數 LPARAM lParam //訊息引數);
2、當系統通知視窗時,會呼叫視窗處理函式同時,將訊息ID和訊息引數傳遞給視窗處理函式。
3、在視窗處理函式中,不處理的訊息,使用預設視窗處理函式,例如DefWindowProc。
四、訊息相關函式
1、GetMessage - 獲取訊息
BOOL GetMessage( LPMSG lpMsg, //存放獲取到的訊息BUFF HWND hWnd, //接收視窗控制代碼,如果是空,所有訊息都管 UINT wMsgFilterMin,//獲取訊息的最小ID 0,如果是0,所有訊息id都管 UINT wMsgFilterMax //獲取訊息的最大ID 0);
lpMsg - 當獲取到訊息後,將訊息的引數存放到MSG結構中。
hWnd - 獲取到hWnd所指定視窗的訊息。
wMsgFilterMin和wMsgFilterMax -只能獲取到由它們指定的訊息範圍內的訊息,如果都為0,表示沒有範圍。
2、TranslateMessage - 翻譯訊息。將按鍵訊息,翻譯成字元訊息。
BOOL TranslateMessage( CONST MSG* lpMsg //要翻譯的訊息地址)
檢查訊息是否是按鍵的訊息,如果不是按鍵訊息,不做任何處理,繼續執行。
3、DispatchMessage - 派發訊息。將訊息派發到該訊息所屬視窗的視窗處理函式上
LRESULT DispatchMessage( CONST MSG* lpmsg //要派發的訊息);
五、windows常用訊息
1、WM_DESTROY:視窗被銷燬時的訊息,無訊息引數。常用於在視窗被銷燬之前,做相應的善後處理,例如資源、記憶體等。
lParam:滑鼠位置
LOWORD:低字,水平位置
HIWORD:高字,垂直位置
3、WM_CREATE:在視窗建立成功還未顯示之前,收到這個訊息。常用於初始化視窗的引數、資源等等,包括建立子視窗等。
WPARAM:不使用,LPARAM:是CREATESTRUCT結構的指標,儲存了CreatWindowEx中的12個引數。
4、WM_SIZE:在視窗的大小發生變化後,會收到WM_SIZE。常用於視窗大小變化後,調整視窗內各個部分的佈局。
WPARAM:視窗大小變化的原因。
LPARAM:變化視窗客戶區的大小
LOWORD:變化後的寬度
HIWORD:變化後的高度
5、WM_QUIT:用於結束訊息迴圈處理。
wParam:PostQuitMessage 函式傳遞的引數。
lParam:不使用,當GetMessage收到這個訊息後,會返回FALSE, 結束while處理,退出訊息迴圈。
6、WM_PAINT:繪圖訊息 鍵盤訊息 滑鼠訊息 定時器訊息
7、相關程式碼
HINSTANCE g_hInstance = 0;//接收當前程式例項控制代碼HANDLE g_接受控制代碼 = 0;//接收標準輸出控制代碼HWND g_編輯框控制代碼 = 0;//視窗建立前所做的事情void 建立前(HWND hWnd, LPARAM lParam){ CREATESTRUCT* pcs = (CREATESTRUCT*)lParam; char* str = (char*)pcs->lpCreateParams; MessageBox(hWnd,(LPCWSTR)str , L"哎呦", MB_OK); }//DOS視窗void DOS視窗(HWND hWnd, LPARAM lParam){ int DOS高 = LOWORD(lParam); int DOS寬 = HIWORD(lParam); MoveWindow(g_編輯框控制代碼, 0, 0, DOS寬, DOS高, TRUE);//移動視窗,控制元件隨視窗變化 wchar_t szText[256] = {}; swprintf_s(szText, L"寬:%d,高:%d\n", DOS寬, DOS高); WriteConsole(g_接受控制代碼,szText, wcslen(szText) ,NULL,NULL);}//視窗上擺放編輯框void 擺放控制元件(HWND hWnd){ g_編輯框控制代碼= CreateWindowEx(0,L"EDIT",L"",WS_CHILD|WS_VISIBLE|WS_BORDER, 0,0,500,500,hWnd,NULL,g_hInstance,NULL); }//2、訊息處理函式LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam){ //7、處理訊息 switch (msgID) { case WM_SIZE: DOS視窗(hWnd,lParam); break; case WM_CREATE: 建立前(hWnd,lParam); 擺放控制元件(hWnd); break; case WM_SYSCOMMAND: //MessageBox(hWnd,L"哎呦",L"不錯哦",MB_OK); if (wParam==SC_CLOSE) { BOOL res= MessageBox(hWnd, L"要關閉麼?", L"不錯哦", MB_YESNO); if (res==IDYES) { //不用寫,自動處理 } else { return 0; } } break; case WM_DESTROY: PostQuitMessage(0);//銷燬視窗 break; } return DefWindowProc(hWnd, msgID, wParam, lParam);}//3、註冊函式,第一個引數,視窗類名稱,第二個引數,指向視窗處理函式的函式指標void Register(LPSTR lpClassName, WNDPROC winProc){ WNDCLASSEX wc = { 0 }; wc.cbSize = sizeof(wc);//結構體大小 wc.cbClsExtra = 0;//視窗類的申請快取區,0表示不開啟快取 wc.cbWndExtra = 0;//視窗的申請快取區,0表示不開啟快取 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//背景顏色,一般白色 wc.hCursor = NULL;//設定游標。null表示預設 wc.hIcon = NULL;//預設左上角的圖示 wc.hInstance = g_hInstance;//第一個引數例項控制代碼,可以找到程序在那塊記憶體 wc.lpfnWndProc = winProc; //lp 一般都是指標,處理函式名或指標 wc.lpszClassName = (LPCWSTR)lpClassName;//視窗類名稱,比如公司名字 wc.lpszMenuName = NULL;//沒有選單用null wc.style = CS_HREDRAW | CS_VREDRAW;//視窗變化,會重繪,視窗類的一般風格 RegisterClassEx(&wc);}//4、建立視窗,(視窗類名稱,視窗標題欄名稱)HWND CreateMain(LPCWSTR lpClassName, LPCWSTR lpWindowName){ HWND hWnd = CreateWindowExW(0, lpClassName, lpWindowName, WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, g_hInstance, (LPVOID)L"附加資料"); return hWnd;}//5、顯示視窗(視窗控制代碼)void Display(HWND hWnd){ ShowWindow(hWnd, SW_SHOW);//控制代碼,顯示方式 UpdateWindow(hWnd);//呼叫一次重新整理視窗}//6、訊息迴圈void Message(){ MSG nMsg = { 0 }; while (GetMessage(&nMsg, nullptr, 0, 0)) { TranslateMessage(&nMsg); DispatchMessage(&nMsg); }}//1、入口函式int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPSTR lpCmdLine, int nCmdShow){ g_hInstance = hInstance; AllocConsole();//增加一個dos視窗 g_接受控制代碼 = GetStdHandle(STD_OUTPUT_HANDLE); Register(LPSTR(L"主"), WndProc); HWND hWnd = CreateMain(LPCWSTR(L"主"), LPCWSTR(L"主視窗")); Display(hWnd); Message(); return 0;}
8、執行結果