我有一个可以向另一个应用程序发送消息的应用程序。在Win8之前的系统中,运行正常。你给它类或标题,它使用enumwindows并找到目标窗口。使用Win8,您只能枚举顶级窗口,这意味着TApplication类。发送方对此感到满意,但接收方并非如此。
要抓住我在目标表格中使用此代码的消息......
function Tmain.AppMsgHookFunc(var wmsg : TMessage) : Boolean;
begin
Result := False;
if wmsg.Msg = WM_COPYDATA then begin
// Post the caught message back to this form.
postmessage (handle,wmsg.Msg,wmsg.WParam,wmsg.LParam);
end;
end;
...然后使用application.hookmainwindow等激活它。
这永远不会开火。我看到,如果我使用sendmessage向自己发送消息,那么它确实会触发,但是如果我使用的postmessage不起作用,即使在XP上也是如此。有什么建议吗?
答案 0 :(得分:6)
WM_COPYDATA
是已发送的消息。系统整理数据跨进程。为此,系统必须知道消息已被处理,以便能够整理用于进行跨进程编组的资源。系统知道消息已被处理的方式是强制您同步发送消息。这意味着您必须使用SendMessage
而不是PostMessage
。
documentation也包含此信息,但您确实需要知道如何解释它。
应用程序发送WM_COPYDATA消息以将数据传递给另一个应用程序。
请注意使用“发送”一词。这是同步消息的代码。
Raymond Chen在这里讨论了这个问题:Why can't I PostMessage the WM_COPYDATA message, but I can SendMessageTimeout it with a tiny timeout?
与消息相似的重要区别 WM_COPYDATA是带有已发送消息的,窗口管理器知道何时 消息处理完成:窗口过程返回时。在 那个时候,它可以释放用于编组的临时缓冲区 从发件人到收件人的邮件。如果邮件已发布, 窗口管理器永远不会确定。
假设消息作为a的结果放在MSG结构中 调用GetMessage。现在窗口管理器知道接收了 线程有可能对消息和消息采取行动 缓冲区需要有效。但是如何知道缓冲区何时可以 被释放? “好吧,你可以等到完全相同的参数得到 将MSG结构传递给DispatchMessage函数。“但是什么 如果消息循环丢弃该消息?或者,如果它决定 发两次?或者,如果它决定将其走私到另一个内部,该怎么办? 消息?
发布消息不保证交付也不提供任何消息 有关消息何时被明确处理的信息,或 即使它已被处理完毕。如果窗口管理器让你 发布WM_COPYDATA消息后,它必须使用其心灵能力 知道什么时候可以释放内存。