Jak przesłać łańcuch do innego programu

Wolverine

Czasami istnieje potrzeba, żeby wysłać do innej aplikacji np łańcuch, którego nie możemy sobie zrzutować na Cardinal i wysłać komunikatem, lecz istnieje na to sposób.

Służy do tego komunikat WM_COPYDATA. Używamy go deklarując strukture TCopyDataStruct, która posiada trzy pola - dwData, cbData i lpData. W lpData podamy wskaźnik do naszych danych a cbData i dwData możemy wykorzystać jak chcemy.

Zacznijmy od programu, który wyśle tekst. Wrzuc na forme TButton i TEdit, nazwy standardowe. OnClick buttona:

procedure TForm1.Button1Click(Sender: TObject);
var
  aCopyData: TCopyDataStruct;
  s: ShortString;
begin
  s := Edit1.Text;
  aCopyData.lpData := @s;
  SendMessage(FindWindow(nil, 'client'), WM_COPYDATA, 0, Longint(@aCopyData));
end;

Teraz program, który to odbierze. Tym razem postaw tylko TEdit ze standardową nazwą a Caption okna ustaw jako 'client'. W definicji formy dopisujemy prototyp funkcji odbierającej dane, wygląda on podobnie jak zwykła funkcja obsługi komunikatu, jednak zamiast parametru TMessage tworzymy TWMCopyData, całość powinna wyglądać tak:

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    procedure CopyData(var Msg: TWMCopyData); message WM_COPYDATA;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

Teraz ciało funkcji:

procedure TForm1.CopyData(var Msg: TWMCopyData);
begin
  Edit1.Text := ShortString(Msg.CopyDataStruct.lpData^);
end;

Zamiast ShortString możemy wysyłać co chcemy, nawet dynamiczne dane (np PChar), w tym wypadku należy razem z komunikatem wysłać długość danych.

5 komentarzy

A w jaki sposób wysłać "StringList"

Szczawik dobrze goda bo bez cbData aplikacja nie dostaje nic - pusty string
a jako wParam powinno się ustawić nie "0" tylko "Handle" - uchwyt okna z którego się wysyła (żeby program do którego się wysyła mógł poprzez Msg.From zlokalizować go

Właśnie taki kod stworzyłem dla Patyka noc wcześniej :) Ale porada na pewno się przyda innym.

P.S. Z tego co wiem, cbData musi zostać wypełnione, nawet przy przesyłaniu napisów:

cbData:=strlen(pchar(lpData));

A tak poza tym, to przykład Microsoft'u:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/dataexchange/datacopy/usingdatacopy.asp

Dzięki, tego właśnie potrzebowałem :D