日期:2014-05-17  浏览次数:20783 次

窗口破坏过程与Windows消息循环

从用户单击关闭按钮(标题栏最右边)或者用鼠标或鍵盘选择系统菜单的“关闭”选项,直到窗口消失,应用程序结束。这期间到底发生了什么呢?这曾经是我百思不得其解的问题,我想也会有很多人和我一样会碰到这个问题。所以我要把我的一些学习心得写出来,与大家共享:??
? 1、首先会产生一个WM_SYSCOMMAND消息,如果程序员没有对此消息进行拦截,则由缺省的窗口函数DefWindowProc进行处理,如果表达式(LOWORD(wParam)&0xFFF0)==SC_CLOSE?? 成立,DefWindowProc发出一个WM_CLOSE消息。??
? 2、同样,如果程序员没有对WM_CLOSE消息进行拦截,则还是由DefWindowProc进行处理,这次,她只简单的调用 DestroyWindow函数,DestroyWindow先把窗口破坏掉,使用户看不到窗口。但是窗口破坏后,应用程序并没有结束,于是 DestroyWindow再接再励,送出了一个WM_DESTROY消息。??
? 3、这一次,WM_DESTROY被载获了,通常是会有这样的句子:??
? case?? WM_DESTROY:??
? PostQuitMessage(0);??
? ...??
? 这里PostQuitMessage函数很简单的发送一个WM_QUIT消息来响应WM_DESTROY??
? 4、WM_QUIT消息非常特殊,她使GetMessage函数返回0,从而结束了消息循环,??
? 应用程序从此结束。??
? 下面我给出完整的证明程序,请大家一试:??
? #include?? <Windows.h>??
? #include?? <TCHAR.h>??
? LRESULT?? CALLBACK?? WndProc(HWND,UINT,WPARAM,LPARAM);??
????????? int?? WINAPI?? WinMain(HINSTANCE?? hInstance,??
??????????????????????????????????????? HINSTANCE?? hPrevInst,??
??????????????????????????????????????? LPSTR?????????? lpszCmdLine,??
??????????????????????????????????????? int???????????????? nCmdShow)??
? {??
????????? HWND?? hwnd;??
????????? MSG?? Msg;??
????????? WNDCLASS?? wndclass;??
????????? char?? lpszClassName[]="窗口";??
????????? char?? lpszTitle[]="窗口示例";??
????????? wndclass.style=CS_HREDRAW?? |?? CS_VREDRAW;??
????????? wndclass.lpfnWndProc?? =WndProc;??
????????? wndclass.cbWndExtra=0;??
????????? wndclass.cbClsExtra?? =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;??
????????? if(!RegisterClass(&wndclass))??
????????? {??
????????????????? MessageBeep(0);??
????????????????? return?? FALSE;??
????????? }??
????????? hwnd=CreateWindow(lpszClassName,??
????????????????????????????????????? lpszTitle,??
????????????????????????????????????? WS_OVERLAPPEDWINDOW,??
????????????????????????????????????????????? CW_USEDEFAULT,??
????????????????????????????????????? CW_USEDEFAULT,??
????????????????????????????????????????????????????? CW_USEDEFAULT,??
????????????????????????????????????????????????????? CW_USEDEFAULT,??
????????????????????????????? NULL,??
????????????????????????????? NULL,??
????????????????????????????? hInstance,??
????????????????????????????? NULL);??
????????? ShowWindow(hwnd,nCmdShow);??
????????? UpdateWindow(hwnd);??
????????? while(1)??
????????? {??
????????????????? GetMessage(&Msg,NULL,0,0);??
????????????????? if(Msg.message==WM_QUIT)??
????????????????? {??
????????????????????????? MessageBox(NULL,_T("收到WM_QUIT,即将跳出消息循环"),_T("注意了"),MB_OK);??
????????????????????????? break;??
????????????????? }??
????????????????? TranslateMessage(&Msg);??
????????????????? DispatchMessage(&Msg);??
????????? }??
????????????????? MessageBox(NULL,_T("已经跳出消息循环,应用程序即将结束!"),_T("注意了"),MB_OK);??
????????? return?? Msg.wParam;??
? }??
? LRESULT?? CALLBACK?? WndProc(??
??????????????????????????????????????????????????? HWND?? hwnd,??
??????????????????????????????????????????????????? UINT?? message,??
??????????????????????????????????????????????????? WPARAM?? wParam,??
??????????????????????????????????????????????????? LPARAM?? lParam)??
? {????
????????? switch(message)??
????????? {??
? case?? WM_CLOSE:??
??????????? MessageBox(NULL,_T("收到WM_CLOSE消息,即将调用?? DestroyWindow(hwnd);"),_T("注意了"),MB_OK);??
??????????? DestroyWindow(hwnd);??
??????????? break;??????????
? case?? WM_DESTROY:??
????????????????? MessageBox