【问题标题】:Sending and receiving Windows messages发送和接收 Windows 消息
【发布时间】:2011-03-09 19:24:15
【问题描述】:

Windows 消息似乎是通知 Windows 操作系统上的应用程序的好方法。它实际上运作良好,但我想到的问题很少:

如何为 SendMessage 例程的 lparam 指定结构化数据(就像许多消息代码一样)?我的意思是……参数当然是一个指针,但是进程如何访问它呢?也许它是由发送/接收消息的进程加载的 DLL 分配的?

是否可以共享消息结构参数(在发送方和接收方之间)?它们是在 send 操作和 peeking 操作之间编组的吗?如果是这种情况,是否可以通过修改结构化参数从调用方返回数据?这对 SendMessage 很有用,因为它是同步执行的,而不是 PostMessage 例程。

其他疑问...

PostMessageSendNotifyMessage 有什么区别?

如果应用程序在处理消息泵时向自己调用 SendMessage,是否可能导致死锁?

【问题讨论】:

    标签: windows winapi sendmessage message-pump


    【解决方案1】:

    如果消息是标准窗口的消息之一 - 通常消息 id 介于 0 和 WM_USER 之间,则系统窗口消息调度逻辑包含将结构编组到消息调度到的任何进程的代码。

    WM_USER 之上的消息没有得到这样的处理 - 这包括 Windows 95 引入的所有常见控制消息 - 您不能结束任何 LVM_*(列表视图消息)或其他新控制消息到不同进程中的控件,并且返回结果。

    WM_COPYDATA 是作为用户代码在进程之间编组任意数据的通用机制而专门引入的 - 在 WM_COPYDATA 之外(或重用其他 Windows 标准消息),没有办法让 Windows 使用消息队列机制自动编组结构化数据进入另一个进程。

    如果是您自己的代码发送和接收消息,您可以使用 dll 来定义共享内存部分,而不是发送指针(每个进程中的 dll 可能基于不同)将偏移量发送到共享内存块。

    如果您想与不对其数据进行编组的外部应用程序交换结构化数据(例如从列表或树视图中提取数据),那么您需要执行 dll 注入,以便您可以发送和处理来自“in -进程”。


    SendNofityMessage 与 PostMessage 不同,因为 PostMessage 总是将消息放入消息队列中,而 SendNotifyMessage 在同一进程中的作用类似于 Windows 的 SendMessage。然后,即使目标窗口在另一个进程中,消息也会直接发送到未放入已发布消息队列的窗口 proc,以便通过 GetMessage 或 PeekMessage 进行检索。


    最后,可能会导致死锁 - 但是在“阻塞”发送消息等待另一个线程回复时,SendMessage 将调度从其他线程发送(未发布)的消息 - 以防止死锁。这可以缓解大多数潜在的死锁,但仍可能通过调用其他阻塞 API 或进入模式消息处理循环来创建死锁。

    【讨论】:

    • 在共享 dll 的堆上分配内存怎么样?
    • 怎么样?我提到过。我还提到它不安全,因为 dll 和共享内存部分可能在每个进程中加载​​到不同的基地址 - 所以接收代码必须意识到这一点 - 这使得它作为与 3rd 通信的一般方式不安全派对代码。
    • @Luca:DLL 通常使用其宿主进程的堆。因此,共享 DLL 并不意味着共享堆。
    【解决方案2】:

    您的担忧主要适用于在进程之间发送消息的情况——在一个进程内,您可以只发送一个指针,发送方只需确保数据在接收方完成使用之前保持有效。

    一些进程间消息要求您使用HGLOBAL(例如,剪贴板消息)。其他需要明确的块大小(例如,WM_COPYDATA)。还有一些以预先指定的结构(例如,以零结尾的字符串)发送数据以支持编组。

    一般来说,您不能通过修改收到的块来返回值。要返回一个值,您需要(例如)发送回复消息。

    SendMessage 有一些(相当复杂的)逻辑来防止死锁,但您仍然需要小心。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      相关资源
      最近更新 更多