Windows消息似乎是在Windows操作系统上通知应用程序的好方法。它实际上运作良好,但很少有问题出现在我的脑海中:
如何为SendMessage例程的 lparam 指定结构化数据(就像许多消息代码一样)?我的意思是......当然参数是一个指针,但进程如何访问呢?也许它是由发送/接收消息的进程加载的DLL分配的?
是否可能共享邮件结构化参数(发件人和收件人之间)?它们是在发送操作和偷看操作之间编组的?如果是这种情况,可以通过修改结构化参数从调用者返回数据吗?这对SendMessage很有用,因为它是同步执行的,而不是PostMessage例程。
其他疑惑......
与 PostMessage 和 SendNotifyMessage有何不同?
如果应用程序在处理消息泵时调用SendMessage,是否有可能导致死锁?
答案 0 :(得分:4)
如果消息是标准窗口的消息之一 - 通常消息ID介于0和WM_USER之间,那么系统窗口消息调度逻辑包含将结构编组到消息被分派到的任何进程的代码。
WM_USER上面的消息没有得到这样的处理 - 这包括Windows 95引入的所有常见控制消息 - 您不能将任何LVM_ *(列表视图消息)或其他新控制消息结束到不同进程中的控件得到一个结果。
WM_COPYDATA专门用作用户代码的通用机制,用于在进程之间封送任意数据 - 在WM_COPYDATA之外(或重用其他Windows标准消息),无法使用消息队列机制自动封送结构化数据的窗口进入另一个过程。
如果你自己的代码正在发送和接收消息,你可以用一个dll来定义一个共享内存部分,而不是发送指针(dll可能在每个进程中有不同的基础)向共享内存发送偏移量块。
如果要与不编组数据的外部应用程序交换结构化数据(例如从列表或树视图中提取数据),则需要执行dll注入,以便从“in”发送和处理消息-Process”。
SendNofityMessage与PostMessage不同,因为PostMessage始终将消息放入消息队列中,而SendNotifyMessage在同一进程中就像SendMessage for Windows一样。然后,即使目标窗口在另一个进程中,也会通过GetMessage或PeekMessage将消息直接发送到未放置在已发布消息队列中的窗口proc for retreivel。
最后可能会导致死锁 - 但是在“阻塞”sendmessage等待另一个线程回复时,SendMessage将调度从其他线程发送(未发布)的消息 - 以防止死锁。这可以缓解大多数潜在的死锁,但仍然可以通过调用其他阻塞api或进入模态消息处理循环来创建死锁。
答案 1 :(得分:0)
您的问题主要适用于进程间发送的消息 - 在进程内,您只需发送一个指针,发送方只需确保数据保持有效,直到接收方完成使用它为止。
某些进程间消息要求您使用HGLOBAL
(例如,剪贴板消息)。其他需要明确的块大小(例如,使用WM_COPYDATA
)。还有一些人以预先指定的结构发送数据(例如,以零终止的字符串)来支持编组。
一般来说,您无法通过修改收到的块来返回值。要返回值,您需要(例如)发送回复消息。
SendMessage
有一些(相当复杂的)逻辑来防止死锁,但你仍需要小心。