我试图将一个应用程序从Lazarus移动到Delphi 10.4。我遇到的问题是WM_COPYDATA。
在VB. Net应用程序上:
Dim sarr As Byte() = System.Text.Encoding.[Default].GetBytes(msg)
Dim len As Integer = sarr.Length
Dim cds As COPYDATASTRUCT
cds.dwData = CType(wParam, IntPtr)
cds.lpData = msg
cds.cbData = len + 1
SendMessage(CInt(hWnd), WM_COPYDATA, 0, cds)
在德尔福方面:
WM_COPYDATA :
begin
recvdata := PCopyDataStruct(Message.LParam);
msgtype := recvdata^.dwData;
msglen := recvdata^.cbData;
str := StrPas(PCHAR(Recvdata^.lpData));
msgtype和msglen看起来很好,但是str(lpdata)被损坏了。我认为这与Delphi使用widechar或ANSI有关。
我需要在VB.Net和Delphi10.4端做些什么才能让它们对齐?
谢谢!
1条答案
按热度按时间3ks5zfa01#
在Delphi2009及以后版本中,
PChar
是PWideChar
(16位UTF-16)的别名,但VB.NET代码发送的是8位ANSI编码字节,因此,在Delphi端需要使用PAnsiChar
而不是PChar
(除非您更改VB.NET代码,使用Encoding.Unicode
而不是Encoding.Default
)。顺便说一句,有一个VB.NET代码中的(潜在)错误。DotNet字符串不是以空结尾的,因此如果
msg
是String
,则Encoding.GetBytes(msg)
将不输出空终止符字节(如果msg
是存在空终止符的Char[]
数组,则会出现这种情况)。代码将cds.cbData = len + 1
设置为存在空终止符。它应该设置cds.cbData = len
,然后,在Delphi端,您可以使用SetString()
而不是StrPas()
将PAnsiChar
数据放入一个AnsiString
,然后您可以将其分配给一个原生string
。试试这个:
一旦这样做了,考虑使用
Encoding.UTF8
而不是Encoding.Default
来避免任何非ASCII字符的潜在数据丢失,因为Encoding.Default
是一个特定于语言环境的转换,可能会有丢失,而UTF-8是一个无损转换:一个二个一个一个