Win32 SDK基础(八)之 关于Windows消息机制的详解(图)
发布时间 - 2017-06-06 00:00:00 点击率:次一、 什么是消息
在解释什么是消息之前,我们先讨论一下程序的执行机制问题。大体上说,程序按照执行机制可以分为两类:
第一类是过程驱动。比如我们最早接触编程时写的c程序,又或者单片机程序。这类程序往往预先已经设定好了执行流程,我们执行时只是按部就班的执行;
第二类是事件驱动。事件,相信大家都能够理解。每个事件的发生都是随机的,每个事件都会有发生的时刻,类似生活中的事件。程序中的事件也会有自己的触发点,事件驱动程序就是事先编写好了针对每个事件的处理流程。在windows的操作系统中,消息就是windows中的事件。windows中的几乎每个操作都会触发消息,像我们之前讲过的创建窗口会触发wm_create消息,绘制窗口会触发wm_paint消息,我们点击鼠标、键盘、都会触发相应的消息。
windows的消息被封装成了一个叫做msg的结构体,其原型如下:
typedef struct tagMSG { // msg
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;Hwnd —— 触发消息的窗口的句柄。
Message —— 消息ID。Windows操作系统为每个消息都分配了一个消息ID,这个ID是唯一的。我们在上文中提到过的WM_CREATE本质就是一个整数,就是消息ID。
wParam —— 消息可附带的参数。
lParam —— 消息可附带的参数。
Time —— 发生消息的时刻。
Pt —— 发生消息时鼠标所在的位置。
以上参数对消息来说,缺一不可。
Windows中就是将一个个消息封装成MSG对象,发送消息时,将这些对象放置到消息队列中;获取消息时,也是获取的这些MSG对象。
二、 消息获取
2.1 消息队列
我们说过,在Windows中几乎每个操作都会触发一条消息,这些消息都被发送到消息队列中。何为消息队列?我们可以将其理解为使用了一个存放Msg对象的先进先出的Deque—— Deque
2.2 消息循环
在前面的文章中,我们曾经写过一个消息循环。所谓的消息循环,就是不断的读取我们的进程中的消息队里中的消息,然后在进行处理。
void Message()
{
MSG nMsg = { 0 };
while (GetMessage(&nMsg, NULL, 0, 0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
这里面,GetMessage()不断的在消息队列中抓取消息,其函数原型如下:
GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax)
lpMsg —— 用来存放消息的MSG类型的指针。
hWnd —— 指定取得其消息的窗口的句柄。当其值取NULL时,GetMessage为任何属于调用线程的窗口检索消息。
wMsgFilterMin —— 指定被检索的最小消息值的整数。
wMsgFilterMax —— 指定被检索的最大消息值的整数。
GetMessage()获取到消息后,TranslateMessage会将消息进行翻译,主要是把虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。Windows中每一个键盘按键,都对应了一个宏,这个键盘按键发出的消息就是虚拟键消息。TranslateMessage的作用就是将虚拟键消息转成字符消息WM_CHAR、WM_SYSCHAR等等。
三、消息处理
DispatchMessage的作用就是将消息,分派到我们实现定义好的窗口处理函数中进行处理,下面是我们在之前的文章中定义的窗口处理函数:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);//可¨¦以°?使º1GetMessage返¤¦Ì回?0
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
hWnd就是产生消息的窗口句柄,uMsg是传递的消息,wParam和lParam分别是消息携带的两个参数。在上面的窗口处理函数中,我们定只处理了一个消息WM_DESTROY,这是我们在点击窗口的关闭按钮后产生的一个消息。我们说过,我们在创建窗口是,也会产生一个WM_CREATE消息。下面我们在窗口处理函数中处理这个消息:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTR
OY:
PostQuitMessage(0);//可¨¦以°?使º1GetMessage返¤¦Ì回?0
break;
case WM_CREATE:
MessageBox(NULL,"WM_CREATE消息被处理了","消息处理",MB_OK);
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
我们在接受到WM_CREATE后,会弹出一个对话框。预期的效果是点击这个对话框的确定按钮后才会显示窗口。如下面所示:
运行程序,先弹出对话框:
点击确定按钮后,弹出窗口:
# 句柄
# 自己的
# 对话框
# 会有
# 好了
# 说过
# 弹出
# 操作系统
# 都是
# 这是
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
Laravel如何记录自定义日志?(Log频道配置)
大连 网站制作,大连天途有线官网?
高端企业智能建站程序:SEO优化与响应式模板定制开发
Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门
Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
如何在IIS中新建站点并配置端口与物理路径?
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
实现点击下箭头变上箭头来回切换的两种方法【推荐】
C#如何调用原生C++ COM对象详解
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
javascript中的数组方法有哪些_如何利用数组方法简化数据处理
郑州企业网站制作公司,郑州招聘网站有哪些?
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录
今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】
*服务器网站为何频现安全漏洞?
如何为不同团队 ID 动态生成多个“认领值班”按钮
js实现获取鼠标当前的位置
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
如何在万网主机上快速搭建网站?
文字头像制作网站推荐软件,醒图能自动配文字吗?
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
如何快速搭建高效服务器建站系统?
Laravel PHP版本要求一览_Laravel各版本环境要求对照
如何快速启动建站代理加盟业务?
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中
SQL查询语句优化的实用方法总结
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
Laravel如何与Inertia.js和Vue/React构建现代单页应用
详解vue.js组件化开发实践
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
如何打造高效商业网站?建站目的决定转化率
如何在宝塔面板中修改默认建站目录?
Laravel Blade模板引擎语法_Laravel Blade布局继承用法
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
如何用美橙互联一键搭建多站合一网站?
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
JavaScript如何实现音频处理_Web Audio API如何工作?
Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】


OY:
PostQuitMessage(0);//可¨¦以°?使º1GetMessage返¤¦Ì回?0
break;
case WM_CREATE:
MessageBox(NULL,"WM_CREATE消息被处理了","消息处理",MB_OK);
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}