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