我使用vb6 app中的WM_COPYDATA将数据发送到delphi应用程序。在我的系统本地是英语,我正确地接收数据,但在另一个荷兰本地系统,接收文本是乱码。
接收应用程序是delphi,代码是
procedure TReceiverMainForm.WMCopyData(var Msg: TWMCopyData);
var
copyDataType: TCopyDataType;
begin
copyDataType := TCopyDataType(Msg.CopyDataStruct.dwData);
//Handle of the Sender
mmoResult.Lines.Add(Format('WM_CopyData from: %d', [msg.From]));
case copyDataType of
cdtString: HandleCopyDataString(Msg.CopyDataStruct);
end;
//Send something back
msg.Result := mmoResult.Lines.Count;
end;
procedure TReceiverMainForm.HandleCopyDataString(
copyDataStruct: PCopyDataStruct);
var
s: string;
begin
s := PChar(copyDataStruct.lpData);
mmoResult.Lines.Add(s);
end;
修改
这里是发送数据的vb6代码,发送的数据是字符串
Dim buf() As Byte
ReDim buf(1 To LenB(Message))
Call CopyMemory(buf(1), ByVal Message, Len(Message))
cds.dwData = 0
cds.cbData = Len(Message) + 1
cds.lpData = VarPtr(buf(1))
' Send the string.
Dim i As Long
i = SendMessage(lHwnd, WM_COPYDATA, MainForm.hwnd, cds)
谁能告诉我出错了什么?
答案 0 :(得分:3)
VB字符串基于COM BSTR
字符串类型,就像Delphi的WideString
字符串类型一样。 BSTR
是UTF-16编码的Unicode字符串。 LenB()
返回转换为本地计算机当前语言环境时VB字符串占用的字节数。你没有考虑到这一点。您没有正确地将字符串字节复制到缓冲区中,也没有将cds.cbData
字段设置为正确的值。 Len()
返回String中UTF-16编码字符的数量,而LenB()
则返回字节数。对于英语字符串,Len()
和LenB()
将返回相同的值,但对于无法保证的外语。
我建议您按原样发送原始的VB Unicode编码数据,并更改您的Delphi代码,将传入的数据视为Unicode,而不是像目前那样将Ansi视为Ansi(PChar
是Delphi 7中的Ansi,但是是Delphi 2009 +中的Unicode。
您还需要为cds.dwData
字段指定唯一值。 VCL使用WM_COPYDATA
作为其内部数据,因此您必须区分WM_COPYDATA
消息和VCL的消息。
请改为尝试:
cds.dwData = RegisterWindowMessage("MyWMCopyData")
If cds.dwData <> 0 Then
cds.cbData = Len(Message) * 2 ' characters are 2-bytes each
cds.lpData = StrPtr(Message) ' access the string's character buffer directly
' Send the string.
Dim i As Long
i = SendMessage(lHwnd, WM_COPYDATA, MainForm.hwnd, cds)
End If
var
uMyWMCopyDataMsg: UINT = 0;
procedure TReceiverMainForm.WMCopyData(var Msg: TWMCopyData);
var
s: WideString; // you can use UnicodeString in D2009+
begin
if (uMyWMCopyDataMsg = 0) or (Msg.CopyDataStruct.dwData <> uMyWMCopyDataMsg) then
begin
inherited;
Exit;
end;
mmoResult.Lines.Add(Format('WM_CopyData from: %d', [msg.From]));
SetString(s, PWideChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData div SizeOf(WideChar));
mmoResult.Lines.Add(s);
msg.Result := mmoResult.Lines.Count;
end;
initialization
uMyWMCopyDataMsg := RegisterWindowMessage('MyWMCopyData');