windows – 如何从不同的线程执行SendMessage?

当我们发送消息时,“如果指定的窗口是由调用线程创建的,则窗口过程将立即作为子例程调用”.
但是“如果指定的窗口是由不同的线程创建的,则系统切换到该线程并调用相应的窗口过程.线程之间发送的消息仅在接收线程执行消息检索代码时处理.” (取自SendMessage的MSDN文档).

现在,我不明白如何(或更恰当地,何时)调用目标Windows过程.当然,目标线程不会被抢占(程序计数器不会被更改).我认为调用会在某些等待函数(如GetMessage或PeekMessage)中发生,这是真的吗?那个过程在某处详细记录了?

更新:它背后的基本原理由GetQueueStatus()和MsgWaitForMultipleObjects()的QS_SENDMESSAGE标志解释:

QS_SENDMESSAGE
 A message sent by another thread or application is in the queue.

这与MSDN文档中的其他备注一起表示另一个线程发送的消息实际上已发布到队列中.然后,只要调用GetMessage或PeekMessage,就会在任何其他发布消息之前通过直接发送到窗口过程来处理它.

在这看到一些混乱.

根据MSDN文档,当您触摸当前线程的消息队列以进行消息处理时(例如,如果您调用PeekMessage或GetMessage),将处理来自其他线程的所有待处理发送(即非排队)消息 – 传递给WndProc – 然后检查消息队列,所以:

>发送的消息永远不会通过dispatchMessage并尽快处理:

>在当前线程中,它们只是传递给WndProc
>在另一个线程中,它们在任何发布的消息处理之前被处理

>为了能够处理发送的消息,目标线程仍然需要一个消息泵
> PostThreadMessage正如它所声明的那样 – 在线程队列中发布消息 – 这些消息不会被定向到任何窗口,必须经过精心处理
> dispatchMessage处理的唯一消息是由PostMessage或某些系统工具(定时器,事件,用户输入等)创建的消息.
>为了避免死锁,使用SendNotifyMessage,SendMessageTimeout或SendMessageCallback代替不同线程之间的普通SendMessage

有关进一步参考,请研究MSDN PeekMessage条目的“备注”部分.

相关文章

Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...
Windows文件操作基础代码 Windows下对文件进行操作使用的一段...
Winpcap基础代码 使用Winpcap进行网络数据的截获和发送都需要...
使用vbs脚本进行批量编码转换 最近需要使用SourceInsight查看...