FAQ » Win API

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

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

chkam 2014-06-11 10:10

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

Adamo 2005-07-09 15:04

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

Szczawik 2005-07-09 13:47

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:
<url>http://msdn.microsoft.com/libr[...]nge/datacopy/usingdatacopy.asp</url>

Patyk 2005-07-09 11:40

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