读书人

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

发布时间: 2012-07-02 17:46:22 作者: rapoo

窗口破坏过程与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(NULL,_T("已调用过DestroyWindow(hwnd),看不到窗口了吧;"),_T("注意了"),MB_OK);??
????????? MessageBox(NULL,_T("以下处理WM_DESTROY"),_T("注意了"),MB_OK);??
????????? PostQuitMessage(0);??
????????? break;??
? case?? WM_SYSCOMMAND:??
????????? if((LOWORD(wParam)&0xFFF0)==SC_CLOSE)??
????????? {??
??????????????????????? MessageBox(NULL,_T("你关闭了窗口,即将发送WM_CLOSE消息!"),_T("注意了"),MB_OK);??
??????????????? SendMessage(hwnd,WM_CLOSE,0,0);??
????????? }??
????????? //不要添加?? break,否则不能响应其它WM_SYSCOMMAND消息??
? default:??
??????? return?? DefWindowProc(hwnd,message,wParam,lParam);??
????????? }??
????????? return(0);??
? }??
???
? --------------------------------------------??
? 窗口破坏过程与Windows消息循环的补充,增加了对WM_NCDESTROY的处理??
? /**??
? *???????? File?? Name???????????????? :???????? MessageTest.cpp??
? *???????? Version???????????????? :???????? 1.1??
? *???????? Project?? Name???????? :???????? MessageTest??
? *???????? Project?? Type???????? :???????? Win32??
? *???????? Author???????????????? :?????? netcoder??
? *???????????????? Addition?????????????????????????? :???????? 此版本增加了对WM_NCDESTROY的处理,?? 感谢?? lily311?? 的补充????
? */??
???
? #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(NULL,_T("已收到WM_DESTROY,看不到窗口了吧!"),_T("注意了"),MB_OK);??
????????????????????????? break;??
???
????????????????? case?? WM_NCDESTROY:??
????????????????????????? MessageBox(NULL,_T("收到WM_NCDESTROY!"),_T("注意了"),MB_OK);??
????????????????????????? PostQuitMessage(0);??
????????????????????????? break;??
???
????????????????? case?? WM_SYSCOMMAND:??
????????????????????????? if((LOWORD(wParam)&0xFFF0)==SC_CLOSE)??
????????????????????????? {??
????????????????????????????????? MessageBox(NULL,_T("你关闭了窗口,即将发送WM_CLOSE消息!"),_T("注意了"),MB_OK);??????????
????????????????????????????????? SendMessage(hwnd,WM_CLOSE,0,0);??
????????????????????????? }??
????????????????????????? //不要添加?? break,否则不能响应其它WM_SYSCOMMAND消息??
????????????????? default:??
????????????????????????? return?????????? DefWindowProc(hwnd,message,wParam,lParam);??
????????????????? }??
????????????????? return(0);

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/azhang00000/archive/2009/03/05/3961231.aspx

?

LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {    switch(message)       {       case   WM_CLOSE:           MessageBox(_T("收到WM_CLOSE消息,即将调用   DestroyWindow(hwnd);"),_T("注意了"),MB_OK);           DestroyWindow();           break;       case   WM_DESTROY:           MessageBox(_T("已调用过DestroyWindow(hwnd),看不到窗口了吧;"),_T("注意了"),MB_OK);           MessageBox(_T("以下处理WM_DESTROY"),_T("注意了"),MB_OK);           PostQuitMessage(0);        break;       case   WM_SYSCOMMAND:           if((LOWORD(wParam)&0xFFF0) == SC_CLOSE)           {                MessageBox(_T("你关闭了窗口,即将发送WM_CLOSE消息!"),_T("注意了"),MB_OK);               SendMessage(WM_CLOSE,0,0);           }            //不要添加   break,否则不能响应其它WM_SYSCOMMAND消息     }         return CDialog::WindowProc(message, wParam, lParam);}

?

读书人网 >windows

热点推荐