窗口破坏过程与Windows消息循环
来源:互联网 发布:国际淘宝什么意思 编辑:程序博客网 时间:2024/05/18 14:14
从用户单击关闭按钮(标题栏最右边)或者用鼠标或鍵盘选择系统菜单的“关闭”选项,直到窗口消失,应用程序结束。这期间到底发生了什么呢?这曾经是我百思不得其解的问题,我想也会有很多人和我一样会碰到这个问题。所以我要把我的一些学习心得写出来,与大家共享:
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);
- 窗口破坏过程与Windows消息循环
- 窗口破坏过程与Windows消息循环
- 窗口破坏过程与Windows消息循环
- windows 消息机制、窗口过程与线程间消息传递
- windows 消息机制、窗口过程与线程间消息传递
- windows窗口与消息
- Windows 窗口与消息
- windows消息与消息循环
- 理解MiniGUI消息循环和窗口过程
- 理解消息循环和窗口过程(转)
- windows程序设计--窗口与消息
- programming windows-----窗口与消息
- Windows程序设计--窗口与消息
- Windows的消息队列与消息循环
- windows的消息队列与消息循环
- Windows的消息队列与消息循环
- Windows的消息队列与消息循环
- windows编程学习笔记(1)创建窗口与消息循环
- Silverlight Tools 正式版发布附下载地址(11月25日更新 for Silverlight 2 RTW)
- 程序人的感情
- 多核查找-顺序查找也疯狂
- 有关几个WINDOWS隐藏文件的的问题
- C/C++小写数字转换成大写数字
- 窗口破坏过程与Windows消息循环
- 多核中的并行前缀和计算
- cssFloat、styleFloat,currentStyle、document.defaultView.getComputedStyle
- 一步一步搭建免费的Silverlight 2开发环境
- C/C++双链表正排序
- 微软,您的.net为中国程序员带来了什么?
- C/C++二叉排序树
- .net(ADO.NET)数据库研究(1):部分主要类及类关系探秘
- C/C++线性顺序存储结构