我试图让Delphi应用程序通过WM_COPYDATA相互通信。我遇到的问题是发件人应用程序是用Delphi 7编写的,接收器是用Delphi 10.2编写的。我将我的Delphi 7程序代码复制到Delphi 10中,并且通信工作完美。然而,在Delphi 7中使用完全相同的代码会导致我的字符串被传递到接收器应用程序以便被破坏。我使用的代码如下:
我有一个发送方:
procedure TSenderApp.SendString(ToSend: string);
var
copyDataStruct : TCopyDataStruct;
receiverHandle : THandle;
res : integer;
begin
copyDataStruct.dwData := 140500; //use it to identify the message contents
copyDataStruct.cbData := (1+ Length(ToSend))* SizeOf(Char) ;
copyDataStruct.lpData := pchar(ToSend) ;
receiverHandle := FindWindow(PChar('TRecieverApp'),PChar('RecieverApp')) ;
if receiverHandle = 0 then
begin
ShowMessage('CopyData Receiver NOT found!') ;
Exit;
end;
res := SendMessage(receiverHandle, WM_COPYDATA, Integer(Handle),
LPARAM(@copyDataStruct)) ;
end;
在接收方面,我有:
procedure TRecieverApp.WMCopyData(var Message: TMessage);
var
p : PCopyDataStruct;
l : Integer;
s : string;
begin
p := PCopyDataStruct( Message.lParam );
if (p <> nil) then
begin
ShowMessage('New Message Recieved!');
l := p^.cbData;
SetLength( s, (l+1) );
StrLCopy( PChar(s), PChar(p^.lpData), l );
Edit1.Text := s;
end
else
Edit1.Text := 'ERROR';
end;
我做错了什么?或者,为什么消息字符串在从Delphi 7编写的SenderApp发送而不是从Delphi 10编写的SenderApp发送时被破坏?
答案 0 :(得分:6)
您正在使用Char
的本机编码发送和处理数据,在Delphi 7中为AnsiChar
,但在Delphi 10.2中为WideChar
(Delphi在D2009中将所有内容切换为Unicode) 。当Delphi 7将数据发送为ANSI时,Delphi 10.2将其误解为UTF-16。反之亦然。所以你最终都会以腐败结束。
您需要在发送数据之前将数据转换为商定的字符编码,并在接收后将其从该编码转换。
尝试更像这样的事情:
{$IF CompilerVersion >= 24} // XE3+
{$LEGACYIFEND ON}
{$IFEND}
var
MyDataID: UINT = 0;
procedure TSenderApp.SendString(const ToSend: string);
var
copyDataStruct : TCopyDataStruct;
receiverHandle : HWND;
res : LRESULT;
s : UTF8String;
begin
if MyDataID = 0 then
begin
ShowMessage('CopyData ID NOT registered!');
Exit;
end;
receiverHandle := FindWindow('TRecieverApp', 'RecieverApp');
if receiverHandle = 0 then
begin
ShowMessage('CopyData Receiver NOT found!');
Exit;
end;
{$IF CompilerVersion >= 20} // D2009+
s := UTF8String(ToSend);
{$ELSE}
s := UTF8Encode(ToSend);
{$IFEND}
copyDataStruct.dwData := MyDataID; //use it to identify the message contents
copyDataStruct.cbData := Length(s) * SizeOf(AnsiChar);
copyDataStruct.lpData := PAnsiChar(s);
res := SendMessage(receiverHandle, WM_COPYDATA, WPARAM(Handle), LPARAM(@copyDataStruct));
end;
initialization
MyDataID := RegisterWindowMessage('MyDataID');
{$IF CompilerVersion >= 24} // XE3+
{$LEGACYIFEND ON}
{$IFEND}
var
MyDataID: UINT = 0;
procedure TRecieverApp.WMCopyData(var Message: TMessage);
var
p : PCopyDataStruct;
s : UTF8String;
begin
p := PCopyDataStruct(Message.lParam);
if (p <> nil) and (MyDataID <> 0) and (p^.dwData = MyDataID) then
begin
SetString(s, PAnsiChar(p^.lpData), p^.cbData);
{$IF CompilerVersion >= 20} // D2009+
Edit1.Text := String(s);
{$ELSE}
Edit1.Text := UTF8Decode(s);
{$IFEND}
ShowMessage('New Message Received!');
end else
inherited;
end;
initialization
MyDataID := RegisterWindowMessage('MyDataID');
答案 1 :(得分:1)
两个Delphi版本之间的区别是字符串格式。在Delphi 2007及更早版本中,string
使用ANSI格式的1字节AnsiChar
字符。在Delphi 2009及更高版本中,string
使用UTF-16格式的2字节WideChar
字符。您需要在发送数据时将数据转换为通用字符编码。