Отправка текста из VB в приложения Delphi, используя SendMessage

) Я пытаюсь отправить короткий текст из приложения VB в приложение Delphi. Вот код VB: Программа отправителя "Отправитель"

Public Class SendData

 Const WM_COPYDATA = &H4A
 Public Structure CopyDataStruct
    Public dwData As Integer
    Public cbData As Integer
    Public lpData As String
 End Structure

Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
 (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ 
 (ByVal hWnd As Long,  ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As _
 CopyDataStruct) As Long

Private Sub SendData(ByVal cds)
    Dim iHwnd As Long
    Dim SS As String = "Test String less than 30 Char"
    Dim cds As CopyDataStruct
    cds.dwData = 0
    cds.cbData = Len(SS)
    cds.lpData = SS
    iHwnd = FindWindow(0&, "Receive")
    SendMessage(iHwnd, &H4A, Me.Handle, cds) 
End Sub

Вот код Delphi: программа-получатель "Получить"

 procedure TForm1.HandleCopyDataString(copyDataStruct: PCopyDataStruct);
 var
  s : string;
 begin
  s := PChar(CopyDataStruct.lpData);
  cdMemo.Lines.Add(Format('Received data "%s" at %s',[s, TimeToStr(Now)]));
 end;

 procedure TForm1.WMCopyData(var Msg: TWMCopyData) ;
 var
  s : string;
  sText: array[0..255] of Char;
  copyDataType : TCopyDataType;
 begin
  copyDataType := TCopyDataType(Msg.CopyDataStruct.dwData);
  s := PChar(Msg.CopyDataStruct.dwData);
  Form1.cdMemo.Lines.Add(Format('Data from: %d',[msg.From]));
  HandleCopyDataString(Msg.CopyDataStruct);
  case Msg.CopyDataStruct.dwData of 0: //we are being sent a string
  begin
    StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData);
    Form1.Label1.Caption := sText;
  end;
end;
end;

Что я здесь не так делаю? Можно ли отправлять строки из VB в программы Delphi с помощью команды WM_COPYDATA и функции SendMessage?

Помогите мне, пожалуйста:-)

F

1 ответ

Есть несколько вещей не так с вашим кодом Delphi.

  1. dwData поле содержит целое число, но вы приводите его к типу PChar, указатель, а затем назначьте его вашей строке. Это не поле, в котором вы сохранили свои строковые данные. Это lpData,

  2. Переданная вами строка не заканчивается нулем. ОС обещает скопировать только столько байтов, сколько указано в cbData поле. Это не обязательно проблема, но вы должны знать об этом, когда будете читать строку позже. Назначить s чтобы сохранить строку, скопированную из другого процесса, используйте SetString как это:

    SetString(s, PAnsiChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData);
    
  3. Вы не показали, что TCopyDataType есть, но если это что-то отличное от целочисленного или целочисленного поддиапазона, вы используете его неправильно. dwData поле уже DWord, так что вы можете использовать его там, где ожидается числовое значение.

  4. Ты звонишь StrLCopy неправильно. Третий параметр должен быть размером буфера назначения, а не источника. Он предназначен для предотвращения переполнения буфера, не копируя больше символов, чем уместится в месте назначения. Ожидается, что функция сможет определять размер исходного буфера, находя завершающий нулевой символ (но мы уже установили, что он не будет доступен). Вы можете исправить это так:

    StrLCopy(sText, Msg.CopyDataStruct.lpData,
      Min(Length(sText), Msg.CopyDataStruct.cbData));
    

    (Min находится в математическом блоке.)

Другие вопросы по тегам