以下内容摘自<<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到底是如何工作的?的更多相关文章

  1. 那么 Appium 到底是怎么工作的呢?

    因为官网文档写的没有梯度,作为新手的我花了好几个小时硬是没看明白它是怎么工作的. 网上教程也基本都是翻译,所以结构很复杂.和其他技术耦合度很高,且没有说明. 我自己总结了一份超简单 Appium 自动 ...

  2. 有一部分程序员还不知道Java 中的注解到底是如何工作的?

    作者:人晓 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解. 这篇文章中, ...

  3. Java中的注解到底是如何工作的?

    作者:人晓 www.importnew.com/10294.html 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Over ...

  4. IPFS 到底是怎么工作的?

    简介 我们知道,一个存储服务,最基本的功能就是存和取.IPFS 中提供了这两种语义,那就是 add 和 get 操作. 在 IPFS 系统中执行 add 操作,就是执行了一次存操作,放在网络的概念里, ...

  5. python3多线程应用详解(第二卷:多线程到底是怎么工作的)

    现在很多人都说用多线程工作快是因为多个不同任务可以同时执行,注意我说的是不同任务,要是重复做一件事达到相同效果就是画蛇添足了,其实这是个错误的说法,线程真正的本质是无法同时执行的.现在我们来看下多线程 ...

  6. 【转】Android开发实践:自定义带消息循环(Looper)的工作线程

    http://ticktick.blog.51cto.com/823160/1565272 上一篇文章提到了Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也 ...

  7. (转)完全用GNU/Linux工作 by 王珢

    完全用GNU/Linux工作 王珢      (看完这篇博文,非常喜欢王珢的这篇博客,也我坚定了学gnu/linux的决心,并努力去按照国外的计算机思维模式去学习编程提高自己.看完这篇文章令我热血沸腾 ...

  8. PHP底层工作原理

    最近搭建服务器,突然感觉lamp之间到底是怎么工作的,或者是怎么联系起来?平时只是写程序,重来没有思考过他们之间的工作原理: PHP底层工作原理 图1 php结构 从图上可以看出,php从下到上是一个 ...

  9. XSLT 处理程序是如何工作的

    与 JSP.PHP 和其他 Web 开发语言的比较 在本文中,Benoit Marchal 考察了 XSLT 处理程序的工作原理.为了说明他的观点,他编写了专门的样式表把处理中的某些方面凸显出来.他特 ...

随机推荐

  1. 对于大于等于3的整数n,在区间【n,3/2 * n】中一定存在一个素数

    对于大于3的整数n,在区间[n,3/2 * n]中一定存在一个素数

  2. 【转帖】PostgreSQL之 使用扩展Extension

    PostgreSQL之 使用扩展Extension https://www.cnblogs.com/lnlvinso/p/11042677.html 挺好的文章.自己之前没有系统学习过 扩展.. 目前 ...

  3. ESXi 虚拟机 提示 无法打开本地虚拟机的 xxx.vmx 的本地管道的 问题解决.

    1. 今天同事与我联系, 说一个虚拟机出现连不上, vcenter控制台关闭虚拟机之后 再次打开报错: 2. 自己最开始的解决方法 移除虚拟机, 进入服务器的datastore 重新注册, 结果发现问 ...

  4. *#【Python】【基础知识】【模块】【tkinter】【学用tkinter画图/制作窗口】

    Python 提供了多个图形开发界面的库,几个常用 Python GUI 库如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 . Tk ...

  5. ajax提交 的编码小结

    今天用ajax的post方法提交数据给webservice,由于有email的缘故发现,注册方法调用总是报错,打开报文一看提交的 发现@符号被变成了%40 , abc@126.com 即abc%401 ...

  6. HashMap集合排序方法

    首先我们先来看看Map集合获取元素的三种常见方法(1)entrySet(),(2)keySet(),(3)values() 1. entrySet():(1)先返回map集合的所有"映射&q ...

  7. 2019年08月21日 服务部署笔记 请求打不到域名后某个pod上

    背景: 一个小项目http+https的小项目, 需要配置域名, 因http 和 https服务共存, 所以决定域名后面挂两个不同的LVS, 80端口一个, 443端口一个. 服务框架: nginx服 ...

  8. J.U.C之AQS介绍

    从JDK1.5开始,引入了并发包java.util.concurrent(J.U.C),并发容器里的同步容器AQS(AbstractQueuedSynchronizer)是J.U.C的核心,AQS底层 ...

  9. fastdfs 集群搭建

    1.部署FastDFS及Nginx (本套FastDFS为简化版安装部署,只需解压至普通用户家目录下或者任意目录,解压后修改脚本,执行脚本后即可使用.) 说明:FastDFS分为tracker(默认端 ...

  10. 第11章:使用Python打造MySQL专家系统

    1.Python语言高级特性 1).深入浅出Python生成器 1).生成器函数:与普通函数定义类似,使用yield语句而不是return语句返回结果.yield语句一次返回一个结果,在每个结果中间挂 ...