プログラム間でデータを渡したいときがあります。ウインドウプログラムにデータをを渡したいときは、送信側はAPIのSendMessageメソッドで送り、受信側はWndProcのメッセージループで受け取ることで、データが渡せます。データは数値および文字列で転送することができますが、文字列で転送するときは、構造体の「COPYDATASTRUCT」を使用します。
受信側プログラム
受信側のプログラムを次に示します。メッセージ受信のために、overrideを用いて、WndProcをフックします。メッセージを受信すると、「WM_USER」と「WM_COPYDATA」で処理を分岐させ、それぞれ数値または文字列として処理を行います。また、メッセージ送信側へ任意の戻り値を返すこともできます。
//COPYDATASTRUCT構造体 public struct COPYDATASTRUCT { public Int32 dwData; //送信する32ビット値 public Int32 cbData; //lpDataのバイト数 public string lpData; //送信するデータへのポインタ(0も可能) } public const int WM_COPYDATA = 0x4A; public const int WM_USER = 0x400; public FomGetMessage() { InitializeComponent(); } protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_USER: //数値が送信されて来た Debug.WriteLine(m.WParam + "スタート!"+m.LParam); break; case WM_COPYDATA: //文字が送信されて来た COPYDATASTRUCT mystr = new COPYDATASTRUCT(); Type mytype = mystr.GetType(); mystr = (COPYDATASTRUCT)m.GetLParam(mytype); Debug.WriteLine(mystr.lpData); break; } base.WndProc(ref m); }
送信側プログラム
送信側のプログラムを次に示します。メッセージを送信したい相手のウインドウハンドルがわからない場合、FindWindowを用いれば特定の相手のウインドウハンドルを取得できます。この取得したウインドウハンドルを指定してSendMessageを呼ぶことで、特定のウインドウにメッセージを送信できます。メソッドは、「SendMessage」ですが、数値を送るときは「WM_USER」、文字列を送るとき「WM_COPYDATA」で、それぞれパラメータが異なります。
[DllImport("User32.dll", EntryPoint = "FindWindow")] public static extern Int32 FindWindow(String lpClassName, String lpWindowName); [DllImport("User32.dll", EntryPoint = "SendMessage")] public static extern Int32 SendMessage(Int32 hWnd, Int32 Msg, Int32 wParam, ref COPYDATASTRUCT lParam); [DllImport("User32.dll", EntryPoint = "SendMessage")] public static extern Int32 SendMessage(Int32 hWnd, Int32 Msg, Int32 wParam, Int32 lParam); public const Int32 WM_COPYDATA = 0x4A; public const Int32 WM_USER = 0x400; //COPYDATASTRUCT構造体 public struct COPYDATASTRUCT { public Int32 dwData; //送信する32ビット値 public Int32 cbData; //lpDataのバイト数 public string lpData; //送信するデータへのポインタ(0も可能) } public FomSendMessage() { InitializeComponent(); Int32 result = 0; //相手のウィンドウハンドルを取得 Int32 hWnd = FindWindow(null, "Receive"); if (hWnd == 0) { //ハンドルが取得できなかった MessageBox.Show("相手Windowのハンドルが取得できません"); return; } //文字列メッセージを送信 //送信データをByte配列に格納 COPYDATASTRUCT cds; cds.dwData = 0; //使用しない cds.lpData = "Tomosoft string";//テキストのポインターをセット cds.cbData = cds.lpData.Length + 1; //長さをセット //文字列を送る result = SendMessage(hWnd, WM_COPYDATA, 0, ref cds); //数値メッセージを送信 Int32 int1 = 3; Int32 int2 = 2; //数値を送る result = SendMessage(hWnd, WM_USER, int1, int2); }
SendMessageによるプログラム間のメッセージ転送
始めにメインメニューでデバッグ→デバッグ開始を選択して、受信側のプログラムを実行し、次に送信側のプログラムを実行すると(順番を決めたのは、起動すると送信側のプログラムはSendMessageメソッドでメッセージを送信するため)、次の結果が受信側の出力のウインドウに表示され、データが受け取れたことがわかります。