我正在尝试使用从此处改编的代码在两个Delphi表单之间发送一个字符串:http://delphi.about.com/od/windowsshellapi/a/wm_copydata.htm。
接收方显示的字符串部分是垃圾。我怀疑这是因为当我使用Windows API与Delphi 2010进行通信时,我会发出Unicode。
我希望能够在可能的情况下处理Unicode。
我一直无法弄清楚下面的代码在哪里出错了。有什么帮助吗?
发送表单:
procedure TForm1.gridDetailsDblClick(Sender: TObject);
var
StringToSend : String;
CopyDataStruct : TCopyDataStruct;
begin
StringToSend := StringGrid1.Cells[0, StringGrid1.Row];
CopyDataStruct.dwData := 0;
CopyDataStruct.cbData := 1 + Length(StringToSend) ;
CopyDataStruct.lpData := PChar(StringToSend) ;
SendDataToAppearanceForm(copyDataStruct) ;
end;
procedure TForm1.SendDataToAppearanceForm(const CopyDataStruct: TCopyDataStruct) ;
var
ReceiverHandle : THandle;
begin
ReceiverHandle := FindWindow(PChar('TForm2'), nil);
if (ReceiverHandle <> 0) then
SendMessage(receiverHandle, WM_COPYDATA, Integer(Handle), Integer(@CopyDataStruct)) ;
end;
接收表单:(这导致编辑框包含字符串的一部分,但随后是垃圾。)
procedure TForm2.WMCopyData(var Msg: TWMCopyData);
var
S: String;
begin
edText.Text := PChar(Msg.CopyDataStruct.lpData);
end; { WMCopyData }
答案 0 :(得分:7)
您的问题是您错误地设置了cbData
。这是字节数而不是字符数。
由于您的接收器将其解释为以null结尾的字符串,因此需要+1
。因此,您的代码应为:
(1 + Length(StringToSend))*SizeOf(Char)
或者,您可以在接收端使用SetString()
和cbdata
来避免使用+1
。
答案 1 :(得分:2)
我刚试过
procedure TForm1.Button1Click(Sender: TObject); // Project1.exe
var
CDS: TCopyDataStruct;
begin
CDS.dwData := 0;
CDS.cbData := (length(Edit1.Text) + 1) * sizeof(char);
CDS.lpData := PChar(Edit1.Text);
SendMessage(FindWindow(nil, 'RecForm'),
WM_COPYDATA, Integer(Handle), Integer(@CDS));
end;
procedure TForm1.WndProc(var Message: TMessage); // Project2.exe
begin
inherited;
case Message.Msg of
WM_COPYDATA:
begin
Edit1.Text := PChar(TWMCopyData(Message).CopyDataStruct.lpData);
Message.Result := Integer(True);
end;
end;
end;
要复制并且有效。此代码与您的代码之间的区别在于,由于一个Unicode字符长两个字节,因此cbData
成员需要是字符串中的两个字符数,即时间sizeof(char)
。此外,您需要添加一个完整的字符,以便将null终止符与字符串一起发送!否则接收器将不知道字符串何时结束!