WM_COPYDATAを使ったプロセス間通信
プロセス間通信のサンプルです。
通信用データにはクラスのストリーミング機能をつかってみました。
フォームのクラス名を"TCommunication"
フォーム上に memSend:TMemo と memRecv: TMemo を作成しておきます。
送信用のボタンも1つ作成します。
またキャプションを'プロセス間通信'としておきます。
//interface部
------ここから--------
type
//フォームの定義。参考までに
TCommunication = class(TForm)
memSend: TMemo;
memRecv: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
//WM_COPYDATAの受信メソッド
procedure WMCopyData(var msg: TWMCopyData);message WM_COPYDATA;
public
end;
//送受信用データ定義
TCommunicateData = class(TComponent)
private
FstringData1:String;
FintegerData1:integer;
published
//ストリーミングの為publishedであることが重要。
property stringData1 :String read FstringData1 write FstringData1;
property integerData1 :integer read FintegerData1 write FintegerData1;
end;
------ここまで--------
TCommunicateDataというクラスをつかって通信します。
publishedなプロパティであればストリーミング機能が使える為
文字の最大長等をあまり気にせず受け渡しが可能です。
※delphiのバージョンが違うものでコンパイルしたEXE同士では正しく通信できない可能性があります。
//implementation部
------ここから--------
//送信処理 ボタンのクリックイベント
procedure TCommunication.Button1Click(Sender: TObject);
var
buf: PChar;
i: Integer;
copydata: TCopyDataStruct;
targetHnd:HWND;
mem:TMemoryStream;
data:TCommunicateData;
begin
//ハンドルをクラス名とフォームキャプションで検索するために
//自分自身のキャプションを変更しておきます。
Caption := 'プロセス間通信 -- 送信中';
//送信先のハンドルを取得
targetHnd := FindWindow('TCommunication','プロセス間通信');
if targetHnd = 0 then raise Exception.Create('送信対象が見つかりませんでした。');
mem := TMemoryStream.Create;
try
//送受信用データを作成
data := TCommunicateData.Create(self);
try
data.stringData1 := memSend.Text;
data.integerData1 := 1;
//送信用データをメモリストリームに書き込む
mem.WriteComponent(data);
//TCopyDataStruct構造体の設定
copydata.dwData := 5963; //メッセージのID なんでもよい
copydata.cbData := mem.Size;
copydata.lpData := mem.Memory;
//送信
SendMessage(targetHnd, WM_COPYDATA, WPARAM(Handle), LPARAM(@copydata));
finally
data.Free();
end;
finally
mem.Free;
end;
Caption := 'プロセス間通信';
end;
//受信処理
procedure TCommunication.WMCopyData(var msg: TWMCopyData);
var
i: Integer;
buf: PChar;
mem:TMemoryStream;
data:TCommunicateData;
begin
//決められたIDのものだけ処理する
if msg.CopyDataStruct.dwData=5963 then begin
mem := TMemoryStream.Create;
try
//メモリストリームにTWMCopyDataから受信したデータを書き込む
mem.Write(Msg.CopyDataStruct^.lpData^,Msg.CopyDataStruct^.cbData);
mem.Seek(0, soFromBeginning);
//送受信クラスをインスタンス化しておき
data := TCommunicateData.Create(self);
try
//メモリストリームからプロパティ値を読み出す
mem.ReadComponent(data);
memRecv.Text := data.FstringData1;
finally
data.Free;
end;
finally
mem.Free;
end;
end
else
inherited;
end;
------ここまで--------
コンパイルして出来たEXEを2つ起動し、片方でmemSendに適当な内容を記入してボタンをクリックしてみてください。
もう片方のmemRecvに受信した内容が出力されるはずです。