SendMessage到底是如何工作的?
以下内容摘自<<Windows核心编程>>:
概要:
SendMessage对于在同一个线程中调用的话,直接调用的是当前线程所属窗口的窗口过程函数(WndProc);如果是跨线程调用SendMessage(),那个这个消息会被放在登记消息队列.登记消息队列中的消息优先级越高,越是能够得到优先响应,处理完成后返回给发送者线程.
详细内容:
如果调用SendMessage()的线程向该线程所建立的窗口发送一个消息, SendMessage()就很简单:它只是调用指定窗口的窗口过程,将其作为一个子例程,当窗口过程完成对消息的处理时,它向SendMessage()返回一个值,SendMessage()再将这个返回值 返回给调用线程即当前线程;
但是,当一个线程向其他线程所建立的窗口发送消息,SendMessage()所做的工作就复杂很多(即使两个线程在同一个进程中也是如此).Windows要求建立窗口的线程处理窗口消息.所以当一个线程调用SendMessage()向一个由其他进程所建立的窗口发送一个消息,也就是向其他线程发送消息,发送者线程不可能处理窗口消息,因为发送者线程不是运行在接收者线程的地址空间中,因此不能访问相应窗口过程的代码和数据.实际上发送者线程要挂起,而由另外的线程处理消息.所以为了向其他线程建立的窗口发送消息,系统必须执行下面将讨论的动作:
首先,发送的消息要追加到接收线程的发送消息队列,同时还为这个线程设定QS_SENDMESSAGE(后面将讨论).其次,如果接收线程已经在执行代码并且没有等待消息(如调用GetMessage,PeekMessage,或WaitMessage)发送的消息不会被处理,系统不能中断线程来立即处理消息.当接收进程在等待消息时,系统首先检查QS_SENDMESSAGE唤醒标志是否被设定,如果是,系统扫描发送消息队列中消息的列表,并找到第一个发送的消息.有可能在这个队列中有几个发送的消息.例如几个线程可以同时向同一个窗口分别发送消息.当发生这样的事时,系统只是将这些消息追加到接收线程的发送消息队列中.
当接收线程等待消息时,系统从发送消息队列中取出第一个消息并调用适当的窗口过程来处理消息.如果在发送消息队列再没有消息了,则QS_SENDMESSAG标志被关闭.当接收线程处理消息的时候,调用SendMessage()函数的发送者线程被置为空闲状态(idle),等待一个消息出现在它的应答消息队列中.在发送的消息处理之后,窗口过程的返回值被登记到发送者线程的应答消息队列中.发送线程现在被唤醒,取出包含在应答消息队列中的返回值.这个返回值就是调用SendMessage()的返回值.这时,发送线程继续正常运行.
当一个线程等待SendMessage()返回时,它基本上是处于空闲状态,但它可以执行一个任务:如果系统中另外一个线程向一个窗口发送消息,这个窗口是由这个等待SendMessage()函数返回的线程所建立的,则系统要立即处理发送的消息,在这种情况下,系统不必等待线程去调用GetMessage,PeekMessage或WaitMessage.
SendMessage到底是如何工作的?的更多相关文章
- 那么 Appium 到底是怎么工作的呢?
因为官网文档写的没有梯度,作为新手的我花了好几个小时硬是没看明白它是怎么工作的. 网上教程也基本都是翻译,所以结构很复杂.和其他技术耦合度很高,且没有说明. 我自己总结了一份超简单 Appium 自动 ...
- 有一部分程序员还不知道Java 中的注解到底是如何工作的?
作者:人晓 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解. 这篇文章中, ...
- Java中的注解到底是如何工作的?
作者:人晓 www.importnew.com/10294.html 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Over ...
- IPFS 到底是怎么工作的?
简介 我们知道,一个存储服务,最基本的功能就是存和取.IPFS 中提供了这两种语义,那就是 add 和 get 操作. 在 IPFS 系统中执行 add 操作,就是执行了一次存操作,放在网络的概念里, ...
- python3多线程应用详解(第二卷:多线程到底是怎么工作的)
现在很多人都说用多线程工作快是因为多个不同任务可以同时执行,注意我说的是不同任务,要是重复做一件事达到相同效果就是画蛇添足了,其实这是个错误的说法,线程真正的本质是无法同时执行的.现在我们来看下多线程 ...
- 【转】Android开发实践:自定义带消息循环(Looper)的工作线程
http://ticktick.blog.51cto.com/823160/1565272 上一篇文章提到了Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也 ...
- (转)完全用GNU/Linux工作 by 王珢
完全用GNU/Linux工作 王珢 (看完这篇博文,非常喜欢王珢的这篇博客,也我坚定了学gnu/linux的决心,并努力去按照国外的计算机思维模式去学习编程提高自己.看完这篇文章令我热血沸腾 ...
- PHP底层工作原理
最近搭建服务器,突然感觉lamp之间到底是怎么工作的,或者是怎么联系起来?平时只是写程序,重来没有思考过他们之间的工作原理: PHP底层工作原理 图1 php结构 从图上可以看出,php从下到上是一个 ...
- XSLT 处理程序是如何工作的
与 JSP.PHP 和其他 Web 开发语言的比较 在本文中,Benoit Marchal 考察了 XSLT 处理程序的工作原理.为了说明他的观点,他编写了专门的样式表把处理中的某些方面凸显出来.他特 ...
随机推荐
- Mybatis插件之Mybatis-Plus的CRUD方法
使用Mybatis-plus进行基本的CRUD(增查改删)操作. 实体类(User)代码: import com.baomidou.mybatisplus.annotation.IdType; imp ...
- Mybatis传递List集合
完整错误如下: org.apache.ibatis.binding.BindingException: Parameter ‘customerIdList’ not found. Available ...
- 飞腾1500A 上面银河麒麟操作系统 进行远程以及添加用户的方法 linux xrdp
1. 安装远程用的软件: sudo apt-get install xrdp vnc4server xbase-clients systemctl enable xrdp systemctl star ...
- 【AtCoder】ARC068
ARC 068 C - X: Yet Another Die Game 显然最多的就是一次6一次5 最后剩下的可能需要多用一次6或者6和5都用上 #include <bits/stdc++.h& ...
- DP_Milking Time
Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that sh ...
- Closest Common Ancestors (Lca,tarjan)
午时刷题,难甚,遂小憩于桌上,惊醒,于梦中有所得,虽大声曰:吾已得tarjan之奥秘! 关于tarjan算法,其实就是一个递归加并查集的应用. 大致代码: #include<bits/stdc+ ...
- 创建web服务器
用node创建本地web服务 1,创建本地文件server.js var http = require('http'); var url=require('url'); var fs=require( ...
- eclipse导入maven空项目,eclipse导入时不识别maven项目
经常我们在网上下载的一些开源项目中,想要导入eclipse中,却发现eclipse不识别这个项目,这时候怎么办呢? 解决办法多种多样,我这里举例出最实用的2种: 1.在项目的根目录中加入.classp ...
- C#数字前补0
[TestMethod] public void Test8() { ; string b = string.Format("{0:000000}", a); , '); }
- C#从服务器下载文件的四种方式
//方法一:TransmitFile实现下载 string fileName = "ss.docx"; //客户端预设的文件名,导出时可修改 string filePath = ...