Отправка текста из 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.
dwData
поле содержит целое число, но вы приводите его к типуPChar
, указатель, а затем назначьте его вашей строке. Это не поле, в котором вы сохранили свои строковые данные. ЭтоlpData
,Переданная вами строка не заканчивается нулем. ОС обещает скопировать только столько байтов, сколько указано в
cbData
поле. Это не обязательно проблема, но вы должны знать об этом, когда будете читать строку позже. Назначитьs
чтобы сохранить строку, скопированную из другого процесса, используйтеSetString
как это:SetString(s, PAnsiChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData);
Вы не показали, что
TCopyDataType
есть, но если это что-то отличное от целочисленного или целочисленного поддиапазона, вы используете его неправильно.dwData
поле ужеDWord
, так что вы можете использовать его там, где ожидается числовое значение.Ты звонишь
StrLCopy
неправильно. Третий параметр должен быть размером буфера назначения, а не источника. Он предназначен для предотвращения переполнения буфера, не копируя больше символов, чем уместится в месте назначения. Ожидается, что функция сможет определять размер исходного буфера, находя завершающий нулевой символ (но мы уже установили, что он не будет доступен). Вы можете исправить это так:StrLCopy(sText, Msg.CopyDataStruct.lpData, Min(Length(sText), Msg.CopyDataStruct.cbData));
(
Min
находится в математическом блоке.)