将消息发送到TApplication

时间:2014-10-10 14:18:28

标签: delphi winapi

我有一个可以向另一个应用程序发送消息的应用程序。在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上也是如此。有什么建议吗?

1 个答案:

答案 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消息后,它必须使用其心灵能力   知道什么时候可以释放内存。