-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 以降を使用している場合 (あなたは言いませんでした)、StringCharが 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 コードから を削除できます。

このコードのもう 1 つの問題は、値として 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また、単なる最適化 -を使用する代わりにからクラスを派生させる場合は、 へのポインターをTMemoryStream渡すことができるため、メッセージ データから直接読み取ることができ、メモリ内に別のコピーを作成する必要はありません。lpDataTCustomMemoryStream.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' と 0 の 2 つの文字であるためです。

于 2013-09-06T16:48:48.040 に答える