向TApplication发送消息

特里

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

大卫·赫弗南(David Heffernan)

WM_COPYDATA是已发送的消息。系统封送数据跨进程。为此,系统必须知道该消息已被处理,以便能够整理用于进行跨进程编组的资源。系统知道消息已被处理的方式是强制您同步发送消息。这意味着您必须使用SendMessage而不是PostMessage

文档也包含此信息,尽管您确实需要知道如何解释它。

应用程序发送WM_COPYDATA消息以将数据传递给另一个应用程序。

注意使用“发送”一词。这是用于同步消息的代码。

Raymond Chen在这里讨论此问题:为什么我不能PostMessage WM_COPYDATA消息,但是我可以在很小的超时时间内发送SendMessageTimeout?

从诸如WM_COPYDATA之类的消息的角度来看,重要的区别在于,对于已发送的消息,窗口管理器知道消息处理何时完成:窗口过程返回时。那时,它可以释放用于封送邮件从发送者到接收者的临时缓冲区。如果消息已发布,则窗口管理器将永远无法确定。

假设由于调用GetMessage而将消息放置在MSG结构中。现在,窗口管理器知道接收线程有可能对消息采取操作,并且缓冲区必须有效。但是,如何知道何时可以释放缓冲区呢?“好吧,您可以等到完全相同的参数以MSG结构形式传递给DispatchMessage函数。” 但是,如果消息循环丢弃该消息怎么办?或者,如果它决定分两次发送该怎么办?或者,如果它决定将其走私到另一封邮件中怎么办?

已发布的消息不能保证传递,也不能提供有关消息何时已被明确处理或什至已被完全处理的任何信息。如果窗口管理器允许您发布WM_COPYDATA消息,则它必须使用其心理能力来知道何时可以释放内存。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章