TSMH’s blog

多趣味人間のメモ

他のアプリの操作-プロセス間通信

delphiで他のアプリケーションを操作したいと思います。
ここの他のアプリとは、同じ Delphi か、開発者自身がコーディング可能なものです
ネットは結構VCLのサンプルはありますが、
なかなかFireMonkeyのがなくて、メモしたいと思います。

イメージ図

ユニットファイル

uses Winapi.Windows, Winapi.Messages ;

送信側

Button1が来ました。

procedure TFmSender.Button1Click(Sender: TObject);
var
  hWindow : HWND; //ウィンドウハンドル
  CDS : TCopyDataStruct;
  Str : String;
  Handle : TWinWindowHandle;
begin
  hWindow := FindWindow(nil, 'Receive'); //通信したいアプリは存在していますか
  if hWindow = 0 then Exit; //存在しない場合

  Str := Edit1.Text;
  Handle := WindowHandleToPlatform(FmSender.Handle);
  CDS.dwData := 1234; //ここは適当な値で大丈夫(識別用?)
  CDS.cbData := (Length(Str) + 1) * SizeOf(Char);  //長さ
  CDS.lpData := Pointer(Str); //内容(ポインター)
  SendMessage(hWindow, WM_COPYDATA, Handle.Wnd, LPARAM(Addr(CDS)));
end;

受信側

受信側結構ややこしいなので、

まず、宣言から

type
  TFmReceive = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
  protected
    procedure WMCopyData(lParam: LPARAM);
  private
    { private 宣言 }
  public
    { public 宣言 }
    function ChangeWndProc: Boolean;
  end;
function Wnd_Proc(hWnd: HWND; uMsg: DWORD; wParam: wParam; lParam: lParam): LRESULT; stdcall;
var
  FmReceive: TFmReceive;
  WndProc: Pointer;

定義

procedure TFmReceive.FormCreate(Sender: TObject);
begin
  ChangeWndProc;
end;

function TFmReceive.ChangeWndProc: Boolean;
var
  Wnd: HWND;
  ptr: Pointer;
begin
  Wnd := FormToHWND(FmReceive); //受信側のウィンドウハンドル
  ptr := @Wnd_Proc;
  WndProc := Pointer(SetWindowLong(Wnd, GWL_WNDPROC, Integer(ptr)));
  Exit(WndProc <> nil);
end;

function Wnd_Proc(hWnd: HWND; uMsg: DWORD; wParam: wParam; lParam: lParam): LRESULT; stdcall;
var
  pcds : ^tagCOPYDATASTRUCT;
  Str : String;
begin
  case uMsg of
    WM_COPYDATA: // などなど
      begin
        FmReceive.WMCopyData(lParam);
      end;
  end;
  Result := CallWindowProc(WndProc, hWnd, uMsg, wParam, lParam);
end;

procedure TFmReceive.WMCopyData(lParam: LPARAM);
var
  pcds : ^tagCOPYDATASTRUCT;
  Str : String;
begin
  pcds := Pointer(lParam);
  if pcds^.dwData = 1234 then //識別
    begin
      Str := PChar(pcds^.lpData); //長さ
      Edit1.Text := Str; //内容
    end;
end;

SendMessageメッセージ一覧

Win32 メッセージ一覧

テストで簡単に使えるやつ(?)
SC_MAXIMIZE    ウィンドウを最大化
SC_MINIMIZE    ウィンドウを最小化
SC_CLOSE    ウィンドウを閉じる

サンプル
SendMessage(hWindow,WM_SYSCOMMAND,SC_MINIMIZE,0);

参考資料

[ 650_他のアプリへデータ ( 文字列や画像 ) の送信 ( Delphi 同士 ) ] - Mr.XRAY