伙计们!
将字符串从 Delphi 10.4 应用程序发送到 Delphi 6 应用程序时会发生奇怪的事情:接收器上仅捕获第一个字符。
我已经在网上找到了一些关于这个问题的其他主题,但我无法解决它。这是代码:
{ 发件人 - Delphi 10.4 }
procedure TfrmMain.sendMessageToApp(psValue: string);
var
DataStruct: CopyDataStruct;
begin
DataStruct.dwData := 0;
DataStruct.cbData := SizeOf(PChar(psValue));
DataStruct.lpData := PChar(psValue);
SendMessage(
FindWindow(nil, PChar(Self.psFormTitleERP)),
WM_COPYDATA, Self.Handle, Integer(@DataStruct));
end;
{ 接收器 - Delphi 6 }
procedure TForm1.WMCopyData(var Msg: TWMCopyData);
var
psMessage: String;
begin
psMessage := PChar(Msg.CopyDataStruct.lpData);
ShowMessage(psMensagem);
end;
我看到的一个有趣的事情是两个版本的 Delphi 之间 tagCOPYDATASTRUCT 的差异:dwData 参数对于 D6 是 DWORD 类型,对于 D 10.4 是 ULONG_PTR 类型。
所以...不知道这些例程有什么问题。有人可以帮助我吗?
谢谢!
认为这可能是一些数据转换错误,但我不太确定 - 不习惯在这个深度中操作字节。
WM_COPYDATA
消息和 COPYDATASTRUCT
结构的文档。根据后者,cbData
成员应该是lpData
成员所指向的数据中的字节数。
您发送
SizeOf(PChar(psValue))
,即 SizeOf(Pointer)
,即 4 或 8,具体取决于您的应用程序是 32 位还是 64 位。
但是您应该发送数据的长度,即
Length(psValue) * SizeOf(Char)
。
在 Delphi 2009 之前,字符串是 ANSI(每个字符 1 个字节)。在 Delphi 2009 及更高版本中,字符串是 Unicode(每个字符 2 个字节)。
此外,在 64 位应用程序中(您的 10.4 应用程序可能是也可能不是),指针是 64 位宽,因此它不适合
Integer
(仍然是 32 位)。所以在 64 位应用程序中,Integer(@DataStruct)
显然是错误的;您丢弃高 32 位。就好像你的电话号码是1234 5678,但你告诉我是0000 5678;我无法给你打电话。
再次回忆一下,字符串在 Delphi 2009 中变成了 Unicode(每个字符 2 个字节)。
因此,您发送一个 Unicode 字符串,接收者期望(并且在某种程度上只能处理)一个 ANSI 字符串。
最简单的解决方案是发送 ANSI 字符串。为此,请使用
AnsiString
和 PAnsiChar
代替 string
和 PChar
。