Question

i am sending data to a delphi app using WM_COPYDATA from vb6 app. in my system which local is english, i receive the data correctly, but on another system with dutch local, the receive text is garbled.

the receiving app is the delphi, the code is

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;

EDIT

here is the vb6 code that is sending the data, the data am sending is string

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)

can anyone tell me what am doing wrong?

Était-ce utile?

La solution

VB strings are based on the COM BSTR string type, just like Delphi's WideString string type is. A BSTR is a UTF-16 encoded Unicode string. LenB() returns the number of bytes that a VB string occupies when converted to the local machine's current locale. You are not taking that into account. You are not copying the string bytes into your buffer correctly, and you are not setting the cds.cbData field to the correct value, either. Len() returns the number of UTF-16 encoded characters in the String, whereas LenB() returns the number of bytes instead. For an English string, Len() and LenB() will return the same value, but for a foriegn language that is not guaranteed.

I suggest you send the original VB Unicode encoded data as-is, and change your Delphi code to treat the incoming data as Unicode instead of Ansi like it is currently doing (PChar is Ansi in Delphi 7, but is Unicode in Delphi 2009+).

You also need to assign a unique value to the cds.dwData field. WM_COPYDATA is used by the VCL for some of its own internal data, so you have to differentiate between your WM_COPYDATA messages and the VCL's messages.

Try this instead:

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');
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top