-1

SendMessage 只发送 VC++ 的第一个消息包,你能帮忙吗?只收到第一份章程。

实际上这是我的完整发件人应用程序代码(VC++)

   // notification->FileName is UCHAR[255]

        HWND app = FindWindow(NULL,TEXT("Message Receiver"));
        COPYDATASTRUCT cds;
    cds.dwData = 0; // can be anything
    cds.cbData = sizeof(notification->FileName) - sizeof(UCHAR);
    cds.lpData = (void*)notification->FileName;
     SendMessageA(app, WM_COPYDATA, (WPARAM)app, (LPARAM)&cds);

我的接收者代码(Delphi)

 procedure TfrmReceiver.WMCopyData(var Msg: TWMCopyData);
    var
      sText: array[0..255] of Char;
      s: string;
      ms: TMemoryStream;
    begin
      case Msg.CopyDataStruct.dwData of
        0: { Receive Text, Text empfangen}
          begin
            StrLCopy(sText, Msg.CopyDataStruct.lpData,Min(Length(sText), Msg.CopyDataStruct.cbData));
            label1.Caption := sText;
          end;
         1: { Receive Image, Bild empfangen}
         {
          begin
            ms := TMemoryStream.Create;
            try
              with Msg.CopyDataStruct^ do
               ms.Write(lpdata^, cbdata);
               ms.Position := 0;
              image1.Picture.Bitmap.LoadFromStream(ms);
            finally
              ms.Free;
            end;
          end; }
      end;
    end;
4

2 回答 2

1

您将数据作为 8 位 Ansi 发送。但是,如果您使用的是Delphi 2009 或更高版本(您没有说),在哪里String以及Char是Unicode,那么您将遇到问题。

将您的 Delphi 代码更改为以下内容,这将适用于所有版本:

procedure TfrmReceiver.WMCopyData(var Msg: TWMCopyData);
var
  sText: AnsiString;
  ms: TMemoryStream;
begin
  case Msg.CopyDataStruct.dwData of
    0: { Receive Text, Text empfangen}
    begin
      SetString(sText, PAnsiChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData);
      Label1.Caption := Trim(sText);
    end;
    1: { Receive Image, Bild empfangen}
    {
    begin
      ms := TMemoryStream.Create;
      try
        with Msg.CopyDataStruct^ do
          ms.Write(lpData^, cbData);
        ms.Position := 0;
        Image1.Picture.Bitmap.LoadFromStream(ms);
      finally
        ms.Free;
      end;
    end;
    }
  end;
end;

如果您更改您的 C++ 代码以发送实际FileName长度而不是总是盲目地发送 255,那么您可以Trim()从 Delphi 代码中删除 。

此代码的另一个问题是 0 和 1 是非常糟糕的dwData值选择。您应该RegisterWindowMessage()在两边都使用来生成更多独特的值,这些值不太可能与其他人的使用发生冲突WM_COPYDATA(例如,即使是 VCL 在WM_COPYDATA内部使用)。例如:

const UINT MyTextMsg = RegisterWindowMessage(TEXT("MyTextMsg"));
// ...
if (MyTextMsg != 0)
{
    COPYDATASTRUCT cds;
    cds.dwData = MyTextMsg;
    // ...
}

var
  MyTextMsg: UINT = 0;
  MyImageMsg: UINT = 0;

procedure TfrmReceiver.WMCopyData(var Msg: TWMCopyData);
var
  sText: AnsiString;
  ms: TMemoryStream;
begin
  if (Msg.CopyDataStruct.dwData = MyTextMsg) and (MyTextMsg <> 0) then
  begin
    // ...
  end
  else if (Msg.CopyDataStruct.dwData = MyImageMsg) and (MyImageMsg <> 0) then
  begin
    // ...
  end;
end;

initialization
  MyTextMsg := RegisterWindowMessage('MyTextMsg');
  MyImageMsg := RegisterWindowMessage('MyImageMsg');

TCustomMemoryStream此外,这只是一种优化 - 如果您从而不是 using派生一个类,TMemoryStream则可以将lpData指针传递给,TCustomMemoryStream.SetPointer()以便LoadFromStream()能够直接从消息数据中读取,并且您不必在内存中制作它的单独副本。

于 2013-09-06T19:13:00.167 回答
0

好像您正在混合 unicode 和 ansi 字符串。在第一种情况下不要使用 TEXT 宏,使用纯 ansi 字符串。片段 sizeof(TEXT("Message Receiver")) - sizeof(UCHAR) 将计算 unicode 字符串的无效大小

当您将 Unicode 字符串 TEXT("Message Receiver") 读取到 delphi char 数组时,它将被视为“M”,因为 unicode 中的 'M' 是两个字符 - 'M' 和零。

于 2013-09-06T16:48:48.040 回答