Windows窗口程序从创建到关闭产生的消息
Windows是消息驱动的,理解消息机制及消息循环是特别重要。知道在什么情况下产生什么消息会让我们对程序有更好的控制。Windows给应用程序发消息,有些会加入应用程序的消息队列,也是就是队列消息。有些直接调用窗口消息处理程序,不会加入到消息队列,这部分为非队列消息。
下面分析一下一个应用程序从创建到结束产生的消息。
先给出测试用的程序,当然是一个非常经典的结构:
#include <windows.h>
#include <tchar.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
MSG msg;
TCHAR szClassName[] = _T("MainWClass");
WNDCLASSEX wndclass; wndclass.cbClsExtra = 0;
wndclass.cbSize = sizeof(wndclass);
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wndclass.hCursor = ::LoadCursor(NULL, IDI_APPLICATION);
wndclass.hIcon = ::LoadIcon(NULL, IDC_ARROW);
wndclass.hIconSm = NULL;
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = szClassName;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW; if (::RegisterClassEx(&wndclass) == 0)
{
::MessageBox(NULL, _T("RegisterClassEx Failed"), _T("Error"), MB_OK | MB_ICONHAND);
return 0;
} HWND hwnd = ::CreateWindow(
szClassName, // lpClassName
_T("My Window"), // lpWindowName
WS_OVERLAPPEDWINDOW, // dwStyle
CW_USEDEFAULT, // X
CW_USEDEFAULT, // Y
CW_USEDEFAULT, // nWidth
CW_USEDEFAULT, // nHeight
NULL, // hWndParent,
NULL, // hMenu
hInstance, // hInstance
NULL // lpParam
); ::ShowWindow(hwnd, nShowCmd);
::UpdateWindow(hwnd); while (::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
} return msg.wParam;
} LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR szText[] = _T("Simple Window!");
switch (message)
{
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
hdc = ::BeginPaint(hwnd, &ps);
::TextOut(hdc, 10, 10, szText, _tcslen(szText));
::EndPaint(hwnd, &ps);
}
return 0;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hwnd, message, wParam, lParam);
}
启动这个程序到关闭他都会产生什么消息呢?
// 调用CreateWindow后产生第一条消息:
CreateWindow()
0X0024 WM_GETMINMAXINFO "当窗口将要改变大小或位置时,由系统发送本消息给窗口,用户拖动一个可重置大小的窗口时便会发出本消息"
0X0081 WM_NCCREATE "当某窗口首次被创建时,本消息在WM_CREATE消息发送前发送"
0X0083 WM_NCCALCSIZE "当某窗口的客户区的大小和位置须被计算时发送本消息"
0X0001 WM_CREATE "新建一个窗口"
CreateWindow() 返回 ShowWindow()
0X0018 WM_SHOWWINDOW "发送本消息给一个窗口,以便隐藏或显示该窗口"
0X0046 WM_WINDOWPOSCHANGING "本消息会发送给那些大小和位置(Z_Order)将被改变的窗口,以调用SetWindowPos函数或其它窗口管理函数"
0X001C WM_ACTIVATEAPP "窗口进程激活状态改动,正被激活的窗口属于不同的应用程序 "
0X0086 WM_NCACTIVATE "本消息发送给某窗口,在窗口的非客户区被激活时重绘窗口"
0X007F WM_GETICON "本消息发送给某个窗口,用于返回与某窗口有关联的大图标或小图标的句柄(一般收到多个,用于获取不同大小的图标)"
0X0006 WM_ACTIVATE "一个窗口被激活或失去激活状态"
0X0281 WM_IME_SETCONTEXT "应用程序的窗口激活时,系统将向应用程序发送WM_IME_SETCONTEXT消息,输入焦点转移到了某个窗口上,注:输入法相关"
0X0282 WM_IME_NOTIFY "可使用WM_IME_NOTIFY消息来通知关于IME窗口状态的常规改变,注:输入法相关,IME窗口发生了改变"
0X0007 WM_SETFOCUS "将焦点转向一个窗口"
0X0085 WM_NCPAINT "当窗口框架(非客户区)必须被被重绘时,应用程序发送本消息给该窗口"
0X0014 WM_ERASEBKGND "当一个窗口的背景必须被擦除时本消息会被触发(如:窗口大小改变时)"
0X0047 WM_WINDOWPOSCHANGED "本消息会发送给那些大小和位置(Z_Order)已被改变的窗口,以调用SetWindowPos函数或其它窗口管理函数"
0X0005 WM_SIZE "改变一个窗口的大小"
0X0003 WM_MOVE "移动一个窗口"
ShowWindow() 返回 UpdateWindow()
0X000F WM_PAINT "窗口重绘"
UpdateWindow() 返回
0X007F WM_GETICON "本消息发送给某个窗口,用于返回与某窗口有关联的大图标或小图标的句柄(一般收到多个,用于获取不同大小的图标)" // 进入消息循环
0X0113 WM_TIMER "发生了定时器事件"
0X0101 WM_KEYUP "当一个非系统按键被释放弹起时(<ALT>键没有被按下),会发送本消息给拥有键盘焦点的窗口"
0X0113 WM_TIMER "发生了定时器事件"
0X0104 WM_SYSKEYDOWN "当用户按住<ALT>键的同时又按下其它键时,发送本消息给拥有焦点的窗口",
0X0112 WM_SYSCOMMAND "当用户选择一条系统菜单命令、用户最大化或最小化或还原或关闭时,窗口会收到本消息"
0X0010 WM_CLOSE "用户关闭窗口时会发送本消息,紧接着会发送WM_DESTROY消息"
0X0046 WM_WINDOWPOSCHANGING "本消息会发送给那些大小和位置(Z_Order)将被改变的窗口,以调用SetWindowPos函数或其它窗口管理函数"
0X0047 WM_WINDOWPOSCHANGED "本消息会发送给那些大小和位置(Z_Order)已被改变的窗口,以调用SetWindowPos函数或其它窗口管理函数"
0X0086 WM_NCACTIVATE "本消息发送给某窗口,在窗口的非客户区被激活时重绘窗口"
0X0006 WM_ACTIVATE "一个窗口被激活或失去激活状态"
0X001C WM_ACTIVATEAPP "窗口进程激活状态改动,正被激活的窗口属于不同的应用程序 "
0X0008 WM_KILLFOCUS "使一个窗口失去焦点"
0X0281 WM_IME_SETCONTEXT "应用程序的窗口激活时,系统将向应用程序发送WM_IME_SETCONTEXT消息,输入焦点转移到了某个窗口上,注:输入法相关"
0X0282 WM_IME_NOTIFY "可使用WM_IME_NOTIFY消息来通知关于IME窗口状态的常规改变,注:输入法相关,IME窗口发生了改变"
0X0002 WM_DESTROY "销毁一个窗口"
0X0082 WM_NCDESTROY "本消息通知某窗口,非客户区正在销毁"
就是以上这些,可以看出上面的消息是使用系统快捷键来关闭的程序。
Windows窗口程序从创建到关闭产生的消息的更多相关文章
- C#Windows Service程序的创建安装与卸载
C#Windows Service程序的创建安装与卸载 一.开发环境 操作系统:Windows7x64 sp1 专业版 开发环境:Visual studio 2013 编程语言:C# .NET版本: ...
- VC菜菜鸟:建立第一个基于Visual C++的Windows窗口程序
建立第一个基于VisualC++的Windows窗口程序: 发表于:http://blog.csdn.net/it1988888/article/details/10306585 a)执行命令:新建 ...
- 我的第一个 Windows 窗口程序(1)
一般来说,构建一个 Windows 程序可以分为如下几个步骤: 定义窗口类(WNDCLASS) 注册窗口类(RegisterClass) 创建窗口(CreateWindow) 更新显示窗口(Updat ...
- [MFC]_在vs2019中使用MFC快速构建简单windows窗口程序
微软基础类库(英语: Classes,简称MFC)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发 ...
- Windows应用程序快捷方式创建工具
说明 在windows中经常用到将程序添加到桌面或者是开始菜单,乘着休息时间就做了这么一个快捷的工具. 程序展示: 用法 1. 命令行(CMD命令窗口) 命令: C:\Users\Administra ...
- OpenGL Windows 窗口程序环境搭建
OpenGL环境搭建步骤: Downloading OpenGL 根据官网的说法: In all three major desktop platforms (Linux, macOS, and Wi ...
- C#自动切换Windows窗口程序,如何才能调出主窗口?
namespace AutoChangeWindow { partial class Form1 { /// <summary> /// 必需的设计器变量. /// </summ ...
- QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数
QT源码解析(一) QT创建窗口程序.消息循环和WinMain函数 分类: QT2009-10-28 13:33 17695人阅读 评论(13) 收藏 举报 qtapplicationwindowse ...
- (Delphi)第一个Windows 32 API的窗口程序
program Project1; uses Winapi.Windows, Winapi.messages; {$R *.res} const className = 'MyDelphiWindow ...
随机推荐
- 洛谷——P1294 高手去散步
P1294 高手去散步 题目背景 高手最近谈恋爱了.不过是单相思.“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求.今天,这个阳光明媚的早晨,太阳从西边缓缓升起.于是它找到高手,希望在晨读开始 ...
- linux time
uint32_t midtime; static struct timeval startstart,midmid; while (ros::ok()) { gettimeofday(&sta ...
- HTTP状态码之200和304
HTTP状态码之200和304 HTTP状态码(HTTP Status Code)是一种表示网页服务器响应状态的三位数字编码.通过这些数字,可以简化状态的表达.状态码有几十种,其中首位数字为1-5 ...
- redis 延迟消息
1.查询下redis 是否打开了键空间通知功能 发现打开了,如果没有打开可以在执行下 我们可以看到参数设置 2.订阅下键空间或者事件通知 订阅键空间:subscribe __keyspace@0__: ...
- webpack 学习笔记 03 Code Splitting
Introduction 对于较大的web 应用来说,将所有的代码文件压缩成一个文件是不合适的,在部分代码文件只有特殊情况下才被需要的情况下,这无疑是一种浪费.webpack 提供了讲代码文件分块的能 ...
- filter和spring 的interceptor都是单例的,都不是线程安全的
Filter 是在 Servlet 容器启动时就初始化的,因此可以认为是以单例对象存在的,如果一个请求线程对其中的成员变量修改的话,会影响到其他的请求线程,因此认为是多线程不安全的.
- Office HPDeskjetD2468 打印机电源灯闪烁不停,打印机不工作怎么办
怎么处理HP DeskjetD2468 打印机电源灯闪烁不停,打印机不工作? 最佳答案 一般电源灯闪烁时因为你的打印喷头上面的盖子没有盖好,你看看.....盖好之后关机再开 谢谢!
- 上传图片/文件到server
package yao.camera.util; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; impo ...
- 用ELK 实时处理搜索日志
转载请标明原处:http://blog.csdn.net/hu948162999/article/details/50563110 本来这块业务 是放到SolrCloud上去的 , 然后 採用solr ...
- Linux基础(2)- 用户、群组和权限
一.用户.群组和权限 1) 新建用户natasha,uid为1100,gid为555,备注信息为“master” 2) 修改natasha用户的家目录为/Natasha 3) 查看用户信息配置文 ...