代码之家  ›  专栏  ›  技术社区  ›  lornova

如何从其他线程执行sendmessage?

  •  8
  • lornova  · 技术社区  · 15 年前

    当我们发送信息时, 如果指定的窗口是由调用线程创建的,则窗口过程将立即作为子例程调用。 “。 但是“ 如果指定的窗口是由其他线程创建的,系统将切换到该线程并调用相应的窗口过程。只有当接收线程执行消息检索代码时,才会处理线程之间发送的消息。 “(摘自 SendMessage )

    现在,我不明白 怎样 (或者更恰当地说, 什么时候 )调用目标Windows过程。当然,目标线程不会被抢占(程序计数器不会更改)。我假定调用将在某个等待函数(如 GetMessage PeekMessage 这是真的吗?在某个地方详细记录了这个过程?


    更新: 其背后的基本原理由 QS_SENDMESSAGE GetQueueStatus() MsgWaitForMultipleObjects() :

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

    这与msdn文档中的其他注释一起意味着由另一个线程发送的消息实际上被发布到队列中。那么,只要 获取消息 窥探信息 被调用时,它将在直接发送到窗口过程之前被处理。

    3 回复  |  直到 8 年前
        1
  •  5
  •   nalzok granmirupa    8 年前

    我看到这里有些混乱。

    根据msdn文档,当您触摸当前线程的消息队列以进行消息处理时(例如,如果您调用 PeekMessage GetMessage ) 全部的 处理来自其他线程的挂起已发送(即非排队)消息-传递给 WndProc -然后检查消息队列,因此:

    • 发送消息 从未 经过 DispatchMessage 并尽快处理:
      • 在当前线程中,它们被简单地传递给 窗口过程
      • 在另一个线程中,它们被处理 在任何之前 已发布消息处理
    • 为了能够处理发送的消息,目标线程仍然需要消息泵
    • PostThreadMessage 做它所说的- 帖子 线程队列中的消息-此类消息不会定向到任何窗口,必须明确处理。
    • 这个 只有 消息处理者 调度消息 那些是由 PostMessage 或某些系统设施(计时器、事件、用户输入等)
    • 要避免死锁,请使用 SendNotifyMessage , SendMessageTimeout SendMessageCallback 而不是平原 SendMessage 在不同的线程之间

    为了进一步参考,请研究msdn的备注部分 窥探信息 条目。

        2
  •  1
  •   selbie    15 年前

    简短回答:当目标线程调用getmessage(或peekmessage),然后调用dispatchmessage时,将接收并处理来自另一个线程的sendmessage。

    我不确定接收到的sendmessage是否优先于队列中的其他消息。不管怎样,从一个线程发送消息到另一个线程就像说:“将此消息发布到另一个线程的消息队列。当线程完成处理后返回”。

    一个你没有要求的答案:

    通常,当我编程主UI线程和工作线程之间的交互时,我尽量避免使用sendmessage。如果不小心,可能会遇到两个线程都死锁的情况。(想想主线程调用waitForSingleObject以等待工作线程完成,但工作线程在将消息发送回UI线程时被阻塞的情况)。

        3
  •  1
  •   Oleg    15 年前

    每个窗口都与一个线程相关联。你可以使用 GetWindowThreadProcessId 检索每个窗口的线程。如果从另一个线程向Windows发送有关 PostThreadMessage 消息将放置在线程的消息队列中。线程必须具有get message循环(使用 GetMessage 例如)获取消息并将其发送到窗口的窗口过程。

    你打电话给我 SendMessage 而不是 Postthreadmessage(Postthreadmessage) 直接调用Windows过程,而不将其放入消息队列。一些未排队的消息也会立即发送到目标窗口过程,绕过系统消息队列和线程消息队列。(见 http://msdn.microsoft.com/en-us/library/ms644927(VS.85).aspx#nonqueued_messages )使用的主要原因 发送消息 而不是 Postthreadmessage(Postthreadmessage) 如果您想从另一个窗口(控件)中提供一些信息,比如在处理另一条消息时从另一个控件中读取文本。只有在真正需要的时候,你才应该这样做。所以如果你使用 发送消息 若要从其他线程向Windows发送消息,必须阻止当前线程一段时间。

    使用它可能是个好主意 Postthreadmessage(Postthreadmessage) SendMessageCallback 而不是 发送消息 如果可能的话。