2

此代码曾经与 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;
4

1 回答 1

4

事实上,你的代码从来都不是正确的。它甚至在 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)

于 2014-04-12T14:49:44.780 回答