Win32 中消息队列如何工作?

2023-12-30

我读了一些关于 Win32 以及消息循环如何工作的内容,但有一些东西我仍然不清楚:消息队列中到底存储了什么?对应于消息的整数值(WM_COMMAND, WM_CREATE等)或指向MSG包含消息整数值和其他内容的结构,例如wParam, lParam, etc?


为了狭隘地回答你的问题,队列中的每条消息至少存储,

  • 消息定向到的窗口句柄,
  • 消息代码 wParam 和 lParam,正如您已经正确指出的那样,
  • 您检索消息的发布时间GetMessageTime(),
  • 对于 UI 消息,消息出现时光标的位置posted (see GetMessagePos()).

请注意,并非所有消息实际上都存储在队列中。发送的消息SendMessage()从拥有该窗口的线程到该窗口的数据永远不会被存储;相反,直接调用接收者窗口的消息函数。从其他线程发送的消息将被存储直到处理,并且发送线程会阻塞,直到消息得到答复(通过退出窗口函数或显式调用ReplyMessage()。 API函数InSendMessage()帮助确定 Windows 函数是否正在处理从另一个线程发送的消息。

您或系统发布的消息都存储在队列中,但有一些例外。

  • WM_TIMER 消息实际上从来没有stored;反而,GetMessage()如果队列中没有其他消息并且计时器已到期,则构造计时器消息。这意味着,首先,定时器消息具有最低的出队优先级,其次,来自短周期定时器的多个消息永远不会溢出队列,即使GetMessage()有一段时间没有被叫到。结果,一个single即使自处理来自该计时器的最后一个 WM_TIMER 消息以来该计时器已经经过多次,也会为给定计时器发送 WM_TIMER 消息。

  • 类似地,WM_QUIT 也不会被存储,而只是被标记。GetMessage()队列耗尽后,假装已检索到 WM_QUIT,这是它检索到的最后一条消息。

  • 另一个例子是 WM_PAINT 消息(向 @cody-gray 致敬以提醒您这一点)。当窗口的任何部分被标记为“脏”并且需要重新绘制时,也会模拟此消息。这也是一条低优先级消息,以便在队列变空时立即重新绘制窗口中的多个无效区域,以降低 GUI 的响应能力并减少闪烁。您可以通过调用强制立即重新绘制UpdateWindow()。这个函数的作用就像SendMessage(),从某种意义上说,直到重新绘制窗口的暴露部分之前它不会返回。这个函数的作用是not如果该窗口的无效区域为空,则发送 WM_PAINT 到该窗口,这是一个明显的优化。

可能还有其他例外和内部优化。

发布的消息PostMessage()最终进入拥有消息发布到的窗口的线程的队列中。

消息在内部以什么形式存储,我们不知道,也不关心。 Windows API 完全抽象了这一点。 MSG 结构填充在您传递给的内存中GetMessage() or PeekMessage()。除了 Windows SDK 指南中记录的内容之外,您无需了解或担心内部实现的细节。


1 我不知道 WM_PAINT 和 WM_TIMER 相对于彼此的优先级到底如何。我认为 WM_PAINT 的优先级较低,但我可能是错的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Win32 中消息队列如何工作? 的相关文章

随机推荐

  • CodeIgniter 应用程序在转移到生产环境时显示 404

    我已经在本地计算机上使用 CodeIgniter 完成了应用程序的开发 并于昨天将其移至生产服务器 实时站点 我的问题是 当我加载网站时 它立即显示 找不到页面 错误 404 我 100 确定这与服务器本身无关 因为干净的 CodeIgni
  • 优化多维通用数组的二进制序列化

    我有一个需要二进制序列化的类 该类包含一个字段 如下所示 private T m data 这些多维数组可以相当大 数十万个元素 并且可以是任何原始类型 当我在对象上尝试标准 net 序列化时 写入磁盘的文件很大 并且我认为 net 存储了
  • Web服务器负载测试工具[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您能否推荐一个软件工具 具有 GPLv 许可证 来执行 Web 服务器的负载测试 Curl 将允许您轻
  • 端口无效。退出..线程“主”org.openqa.selenium.WebDriverException 中出现异常:驱动程序服务器进程过早终止 ChromeDriver Selenium

    安装细节 我已经安装了 java版本 1 8 硒罐版本 3 141 59 Chrome 浏览器版本 84 0 4147 89 我想使用 selenium web driver 测试用例在 chrome 浏览器中启动 google 但由于上述
  • 在 MonkeyTalk IDE Javascript 文件中记录变量的值

    我正在使用 MonkeyTalk IDE Beta2 来测试 iPad 应用程序 我从 MonkeyTalk IDE 导出了 javascript 并获得了一个新的 js 文件 我正在存储 a 的布尔值Verify命令在一个var并想看看它
  • 如何组合 numpy 数组中的维度?

    我在用着OpenCV将图像读入numpy array 并且它们具有以下形状 import cv2 def readImages path imgs for file in os listdir path if file endswith p
  • 从 igraph 中的图中删除未连接的短路径

    我正在 igraph 中使用网络 我有一个网络 其中存在彼此重叠的短连接节点 因此我们看不到边缘 我想删除所有此类短连接节点 因为它们未连接到主网络 度数在这里不起作用 因为节点不是 0 度 它们要么连接到 1 个或多个基因 但仍然不在主网
  • Tomcat 背后的 apache 代理路径错误

    我正在尝试将 apache 2 2 配置为服务器上某些应用程序的代理 tomcat jira 使用 Jira 安装程序安装 tomcat dev 只是其他应用程序的容器 首先 我的httpd conf是这样的 ProxyRequests O
  • BCPL 八进制数值常量

    由于有人问我关于使用前缀 0x 表示十六进制数字背后的推理的问题 我一直在深入研究 BCPL 的历史 在我的搜索中 我偶然发现了这个代币背后历史的非常好的解释 为什么十六进制数以 0x 为前缀 https stackoverflow com
  • 内存映射文件长度

    我正在处理内存映射文件 有没有办法知道内存映射文件内容的长度 我想要的是附加现有的内存映射文件 在文件中附加字节很容易 但我希望附加字符串 我们可以检查 CAPACITY 属性 但它返回我认为的字节大小 为了更清楚地说明 我正在解释这个场景
  • 如何在 UIWebView 中暂停媒体播放

    我目前正在开发一款支持 iPad 上多个选项卡的浏览器 问题是 iOS 不允许多个选项卡同时播放音频 视频 尝试这样做会导致出现问题 例如所有音频停止且无法返回 我注意到 Google Chrome 浏览器实际上会停止非活动选项卡中的媒体
  • 如何在GIT中将一个分支合并到另一个分支?

    让我详细解释一下这个问题 我有一个主 git 分支 在上面创建了一个新的侧分支 bug10101010 现在我不想将 bug10101010 合并到主分支 到目前为止一切都很好 现在我有同一产品的不同分支 名为legacy 我不想将 bug
  • 如何使用 Apache HttpClient 启用 SSLv3?

    Apache 中禁用了 SSLv3Http客户端 https hc apache org从 4 3 6 版本开始 但我使用的是 4 5 版本 这开发人员写道 https hc apache org news html 希望继续使用 SSLv
  • Android 中的视频录制格式(.3gp 或 mp4)?

    我用Intent MediaStore ACTION VIDEO CAPTURE视频录制方法 默认情况下 录制的视频存储为 3gp文件 我想将视频录制并存储为 mp4 file 这可能吗 Yes Set the MediaRecorder
  • 将触摸焦点转移到另一个视图

    这个问题问得有点尴尬 是否可以将一个视图的触摸焦点转移到另一个视图 基本上 假设您有一个选择第一个的视图ACTION DOWN触摸事件 然后立即想要将所有触摸事件的焦点转移到另一个视图来处理它onTouchEvent MotionEvent
  • 将分配器添加到 C++ 类模板以创建共享内存对象

    简而言之 我的问题是 如果你有课 MyClass
  • jQuery:使用预定义函数添加更改事件处理程序

    所以我有以下内容 var change handler function element do some fancy stuff 现在 我想将其附加到一个元素 哪种方法更好 最好或更正确 element selector change ch
  • Maven 3.3.1 ECLIPSE:未设置-Dmaven.multiModuleProjectDirectory 系统属性

    我刚刚在 Mac OS X 上安装了 Maven 3 3 1 并且使用 Eclipse 构建 Maven 项目时出现以下错误 Dmaven multiModuleProjectDirectory system property is not
  • 在哪里设置 celery 任务的task_id?

    我无法找到使用我自己的 task id 设置 task id 的任何示例 沿着这些思路的东西 def testview1 request for i in xrange 0 1000 result add delay i 4 task id
  • Win32 中消息队列如何工作?

    我读了一些关于 Win32 以及消息循环如何工作的内容 但有一些东西我仍然不清楚 消息队列中到底存储了什么 对应于消息的整数值 WM COMMAND WM CREATE等 或指向MSG包含消息整数值和其他内容的结构 例如wParam lPa