delphi 通过 wm_copydata 将运行参数传递给其他实例在 Delphi XE2 中给出错误结果

标签 delphi wm-copydata

此代码用于 Delphi 5,但在 Delphi XE2 中无法按预期工作。使用wm_copydata传递的字符串将被剪切。

procedure SendAppParameters(aMsgStr: string);
var
  hwnd: THandle;
  cds: CopyDataStruct;
begin


  hwnd := FindWindow('TMyAppFormMain', nil); //<-- Substitute window classname with your own
  if hwnd <> 0 then
  begin
   // showmessage(aMsgStr);
    // prepare the data to copy
    cds.dwData := 0;
    cds.cbData := length(AMsgStr);
    cds.lpData := PChar(AMsgStr);
    // activate the destination window
    SetForegroundWindow(hwnd);
    // send the data to the first instance using a wm_CopyData message
    SendMessage(hwnd, wm_CopyData, Application.Handle, integer(@cds));
  end

end;

在主窗体中我有:

procedure TMyAppFormMain.GotMessage_CopyData(var Msg: TWmCopyData);
var
  MsgString: string;
  I: Integer;
begin

  MsgString := PChar(Msg.CopyDataStruct.lpData);
  showmessage(MsgString);


end;

最佳答案

事实上你的代码从来都不正确。它甚至在 ANSI 版本的 Delphi 上也被破坏。

我们来看看吧。您可以像这样准备消息:

cds.cbData := length(AMsgStr);
cds.lpData := PChar(AMsgStr);

在 ANSI Delphi 上,这意味着文本被编码到但不包括空终止符。

接收者这样做:

MsgString := PChar(Msg.CopyDataStruct.lpData);

这依赖于存在空终止符。没有理由期望会出现这种情况,甚至尝试读取超出 cds.cbData 字节的内容也是错误。

接收者必须注意发送的 cds.cbData 值,并且读取的值不得超出缓冲区末尾。

现在,另一个问题是您已转移到 Unicode Delphi,因此文本现在采用 UTF-16 编码。

要发送我要写的文字:

cds.cbData := length(AMsgStr)*SizeOf(Char);
cds.lpData := PChar(AMsgStr);

在接收端应该是:

SetString(MsgString, PChar(Msg.CopyDataStruct.lpData), 
  Msg.CopyDataStruct.cbData div SizeOf(Char));

您使用的转换integer(@cds)不正确。那应该是LPARAM(@cds)

关于delphi 通过 wm_copydata 将运行参数传递给其他实例在 Delphi XE2 中给出错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23031208/

相关文章:

ios - iOS 后台运行任务

c# - 防篡改表

Delphi:类中的记录

delphi - 当 case 变量未命名时,如何判断变体记录中哪种情况有效,以及如何创建此类记录的值?

vb.net - 如何将短字符串从Visual Basic应用程序发送到Delphi应用程序?

delphi - WM_COPYDATA 字符串未出现在目标应用程序中

c - C 中的指针数学与 Delphi 中的指针数学

delphi - WM_COPYDATA 在 Delphi 中没有类

multithreading - 具有隐藏窗口的线程的线程消息循环?