Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SendData results in a mangled string when received

Tags:

delphi

I'm trying to send a string between two Delphi forms using code adapted from here: http://delphi.about.com/od/windowsshellapi/a/wm_copydata.htm.

The string that is displayed by the receiver is partially garbage. I suspect this is because of Unicode I issues when Delphi 2010 is communicating with the Windows API.

I want to be able to handle Unicode if possible.

I have been unable to figure out where in the code below a cast is wrong. Any help?

Sending form:

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;

Receiving form: (Which results in the edit box containing a part of the string, but then garbage.)

procedure TForm2.WMCopyData(var Msg: TWMCopyData);
var
  S: String;
begin
  edText.Text := PChar(Msg.CopyDataStruct.lpData);
end;  { WMCopyData }
like image 884
RobertFrank Avatar asked Jan 20 '23 19:01

RobertFrank


1 Answers

Your problem is that you are setting cbData incorrectly. This is the number of bytes and not the number of characters.

The +1 is needed since your receiver is interpreting it as a null-terminated string. Therefore your code should read:

(1 + Length(StringToSend))*SizeOf(Char)

Alternatively you could, at the receiving end, make use of SetString() and cbdata to avoid the need for the +1.

like image 157
David Heffernan Avatar answered Jan 27 '23 19:01

David Heffernan