2

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

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

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

其他疑问...

PostMessageSendNotifyMessage有什么区别?

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

4

2 回答 2

4

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

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

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

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

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


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


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

于 2010-06-29T19:36:47.377 回答
0

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

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

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

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

于 2010-06-29T19:38:22.117 回答