Delphi 10.4(发送方)和 Delphi 6(接收方)之间 SendMessage 的奇怪行为

问题描述 投票:0回答:1

伙计们!

将字符串从 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 类型。

所以...不知道这些例程有什么问题。有人可以帮助我吗?

谢谢!

认为这可能是一些数据转换错误,但我不太确定 - 不习惯在这个深度中操作字节。

delphi sendmessage
1个回答
0
投票

尺码错误

首先,您应该阅读

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 位指针

此外,在 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

© www.soinside.com 2019 - 2024. All rights reserved.