プログラム間でデータを渡したいときがあります。ウインドウプログラムにデータをを渡したいときは、送信側は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メソッドでメッセージを送信するため)、次の結果が受信側の出力のウインドウに表示され、データが受け取れたことがわかります。
