发送和接收Windows消息

发送和接收Windows消息,windows,winapi,sendmessage,message-pump,Windows,Winapi,Sendmessage,Message Pump,Windows消息似乎是通知Windows操作系统上的应用程序的好方法。它实际上工作得很好,但我想不出什么问题: 如何向SendMessage例程的LPRAM指定结构化数据(就像许多消息代码一样)?我是说。。。当然参数是指针,但是进程如何访问它呢?它可能是由发送/接收消息的进程加载的DLL分配的 是否可以(在发送方和接收方之间)共享消息结构参数?它们在发送操作和窥视操作之间编组?如果是这种情况,是否可以通过修改结构化参数从调用方返回数据?这对于SendMessage很有用,因为它是同步执行的,而

Windows消息似乎是通知Windows操作系统上的应用程序的好方法。它实际上工作得很好,但我想不出什么问题:

如何向SendMessage例程的LPRAM指定结构化数据(就像许多消息代码一样)?我是说。。。当然参数是指针,但是进程如何访问它呢?它可能是由发送/接收消息的进程加载的DLL分配的

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

其他疑问

PostMessage和SendNotifyMessage有什么区别


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

如果消息是标准窗口的消息之一,通常消息id介于0和WM_USER之间,然后,systems窗口消息分派逻辑包含将结构封送到消息分派到的任何进程的代码

WM_USER以上的消息不会得到这样的处理—这包括Windows 95引入的所有常见控制消息—您不能在不同的进程中将任何LVM_*(列表视图消息)或其他新控制消息终止到控件并返回结果

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

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

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


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



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

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

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

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


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

在共享dll的堆上分配内存如何?如何?我提到过。我还提到,它不安全,因为DLL和共享内存段可能在每个进程中加载在不同的基址上,因此接收代码必须知道这一点,这使得它作为与第三方代码通信的一般方式不安全。@Luca:DLL通常使用其主进程的堆。因此,共享DLL并不意味着共享堆。