最近面试,被问到好几次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则是用来退出消息循环的。