使用 SendMessage 将文本从 VB 发送到 Delphi 应用程序

发布于 2024-10-29 17:40:15 字数 1819 浏览 4 评论 0原文

)我正在尝试从 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;

我在这里做错了什么?是否可以使用 WM_COPYDATA 命令和 SendMessage 函数将字符串从 VB 发送到 Delphi 程序?

请帮助我:-)

F

) I am trying to send a short text from a VB app to Delphi app.. here is the
VB Code: Sender Program "Sender"

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

here is the Delphi Code: Receiver program "Receive"

 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;

What am I doing wrong here? It is possible to send strings from VB to Delphi programs using WM_COPYDATA command, and SendMessage function?

please help me :-)

F

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱娆 2024-11-05 17:40:15

您的 Delphi 代码有一些问题。

  1. dwData 字段保存一个整数,但您将其类型转换为 PChar(一个指针),然后将其分配给您的字符串。这不是您存储字符串数据的字段。这就是 lpData

  2. 您传递的字符串不是以 null 结尾的。操作系统仅承诺复制您在 cbData 字段中指定的字节数。这不一定是问题,但是稍后读取字符串时需要注意这一点。要分配 s 来保存从其他进程复制的字符串,请使用 SetString,如下所示:

    SetString(s, PAnsiChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData);
    
  3. You not shown what TCopyDataType is ,但如果它不是整数或整数子范围类型,那么您使用的是错误的。 dwData 字段已经是 DWord,因此您可以在任何需要数值的地方使用它。

  4. 您调用的 StrLCopy 是错误的。第三个参数应该是目标缓冲区的大小,而不是源缓冲区的大小。它的目的是通过不复制超出目标空间的字符来防止缓冲区溢出。该函数期望能够通过查找终止空字符来检测源缓冲区的大小(但我们已经确定这不可用)。你可以这样修复它:

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

    Min 采用数学单位。)

There are a few things wrong with your Delphi code.

  1. The dwData field holds an integer, but you type-cast it to PChar, a pointer, and then assign it to your string. That's not the field where you stored your string data. That's lpData.

  2. The string you pass is not null-terminated. The OS only promises to copy exactly as many bytes as you specify in the cbData field. That's not necessarily a problem, but you need to be aware of it when you read the string later. To assign s to hold the string copied from the other process, use SetString like this:

    SetString(s, PAnsiChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData);
    
  3. You haven't shown what TCopyDataType is, but if it's anything other than an integer or integer-subrange type, you're using it wrong. The dwData field is already a DWord, so you can use it wherever a numeric value is expected.

  4. You're calling StrLCopy wrong. The third parameter should be the size of the destination buffer, not the source. It's meant to prevent buffer overflows by not copying more characters than will fit in the destination. The function expects to be able to detect the size of the source buffer by finding the terminating null character (but we already established that that won't be available). You could fix it like this:

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

    (Min is in the Math unit.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文