最近面試,被問到好幾次WM_CLOSE WM_DESTORY WM_QUIT 的區別這樣的問題,也沒答上來。回來后查了下MSDN,才算明白了他們之間的區別,MSDN的鏈接。
1 int APIENTRY _tWinMain(HINSTANCE hInstance, 2 HINSTANCE hPrevInstance, 3 LPTSTR lpCmdLine, 4 int nCmdShow) 5 { 6 MSG msg; 7 8 //........... 9 10 // 主消息循環: 11 while (GetMessage(&msg, NULL, 0, 0)) 12 { 13 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 14 { 15 TranslateMessage(&msg); 16 DispatchMessage(&msg); 17 } 18 } 19 20 return (int) msg.wParam; 21 } 22 23 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 24 { 25 switch (message) 26 { 27 case WM_CLOSE: 28 if (MessageBox(hWnd, L"Really quit?", L"My application", MB_OKCANCEL) == IDOK) 29 { 30 DestroyWindow(hWnd); 31 } 32 break; 33 case WM_DESTROY: 34 PostQuitMessage(0); 35 break; 36 default: 37 return DefWindowProc(hWnd, message, wParam, lParam); 38 } 39 return 0; 40 }
下面就分析下窗口關閉的流程:
1. WM_CLOSE
當用戶點擊窗口右上角的關閉按鈕或者按下鍵盤的Alt+F4時,窗口會收到WM_CLOSE消息,此時窗口本身,以及窗口的子窗口,都是還存在的。此時可以給用戶一次取消關閉窗口的機會,讓用戶決定是否真的要關閉窗口。用戶確定要關閉該窗口,則調用DestoryWindow,該函數會發送一個WM_DESTORY消息。當然也可以不給用戶取消關閉窗口的機會,直接調用DestoryWindow。
2. WM_DESTORY
在處理WM_DESTORY消息時,此時窗口本身已經不在屏幕上顯示了,但是在該窗口的銷毀前(主要是指該窗口的子窗口銷毀前)。一般情況下會調用PostQuitMessage,該函數會在窗口的消息隊列里放置WM_QUIT消息。
3. WM_QUIT
GetMessage在獲取到WM_QUIT消息時,則返回FALSE,同時while循環結束。
引用下MSDN里的流程圖:
總結.
在用戶想關閉窗口時,處理WM_CLOSE消息,可以讓用戶有取消關閉的機會,或者改變WM_CLOSE的行為,例如QQ可以設置點擊關閉按鈕,是最小化到又下角的任務欄里,還是直接關閉QQ。在處理WM_DESTORY時,該窗口已經不在屏幕上顯示了,也就是說窗口已經開始銷毀了,沒機會取消關閉窗口的操作。WM_QUIT則是用來退出消息循環的。