画像ファイル
画像ファイル  プロセス間通信(SendMessage)
プロセス間通信
1-->プロセス間通信(送信側) -->
2プロセス間通信(受信側)

VB.NET C#全般
1羊の皮を着た狼 VB.NET
2Form1、Form2の相互参照
3Form1、Form2の相互参照 2
4VB.NET C# データ型の基本
5VB.NET C# 文字列
6VB.NET タイマー精度
7BackgroundWorkerの魅力1..
8BackgroundWorkerの魅力2..
9VB6のタイマー
10コントロールの配列をインデクサ..
11コントロールの配列はジェネリク..
12インデクサ(C#、VB.NET)
13インデクサでBit操作
14Unicode 入門
15デリゲート入門
16マルチスレッド入門
17イベント入門
18デリゲートとイベント
18インターフェースの基本

RichTextBox関係
1RichTextBoxの不思議
2テキスト色付け高速化計画
3VB.NET RichTextBox1
4VB.NET RichTextBox 2

RS-232C関係
1RS-232Cの基礎
2RS-232Cの何が変わった..
3SerialPortクラス
4Unicode(ユニコード)の壁
5マルチスレッドの壁
6RS-232C サンプルコード
7RS-232CのHEXモニタ
8RS-232C 送信モジュール
9RS-232Cのループテスト
10RS-232Cのピンチェンジ..

Socket通信
1C#、VB2005 でSocket通信
2サーバー 複数接続


質問、意見はこちらに
画像ファイル


プロセス間通信とは
同一コンピューター上で起動しているアプリケーション間でデータを受け渡したいことは時々有る。
Frameworkには『リモート処理』という方法でデータの受け渡しを行なう方法が有る。
この方法に関してはいずれ又日を改めて説明することにするが、ここでは従来の方法のAPIを使用した、 プロセス間通信を紹介する。
この方法は、送信側はAPIのSendMessageで送り、受信側はWndProcのメッセージループで受け取ることになる。
難しいことはあまり無いのだが、文字列の送受信では構造体のCOPYDATASTRUCTを使うので、この処理が 少々面倒である。

送信側 仕様
画像ファイル
先ず相手のアプリケーション名を入力して、送るメッセージと送る数値を2つ入力して「送信」を押すと 相手にメッセージが投げられるものとする。

コードの説明 宣言
APIは全部で3つ使用する、先ず相手のWindowのハンドルを取得する、「FindWindow」と
相手に数値を送る「SendMessage」と文字列を送る「SendMessage」であるSendMessageは同じ 名前の関数で有るが、引数の形が違います。
始めの関数は引数として1番目に相手のWindowのハンドルを、2番目、3番目に数値を持ちます。
一方2番目の「SendMessage」は1番目は同じで有るが2番目は0を3番目には「COPYDATASTRUCT」と言う 構造体を持ちます。
「COPYDATASTRUCT」は値渡しではなく参照渡し(ref)ですので注意して下さい。
C#コード
[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も可能)
}
VB.NETコード
  'COPYDATASTRUCT構造体
Public Structure COPYDATASTRUCT
Public dwData As Int32 '送信するビット値
Public cbData As Int32 'lpDataのバイト数
Public lpData As String '送信するデータへのポインタ(0も可能)
End Structure

Public Const WM_COPYDATA As Int32 = &H4A
Public Const WM_USER As Int32 = &H400

"user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function

"user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Int32, _
ByVal wParam As Int32, _
ByVal lParam As Int32) As Integer
End Function

"user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Int32, _
ByVal wParam As Int32, _
ByRef lParam As COPYDATASTRUCT) As Integer
End Function

データの送信
C#コード
     //送信ボタン押下
private void butSend_Click(object sender, EventArgs e)
{
Int32 result = 0;

//相手のウィンドウハンドルを取得します
Int32 hWnd = FindWindow(null, txtName.Text);
if (hWnd == 0)
{
//ハンドルが取得できなかった
MessageBox.Show("相手Windowのハンドルが取得できません");
return;
}

//文字列メッセージを送信します
if (txtMessage.Text != string.Empty)
{
//送信データをByte配列に格納
byte[] bytearry =
             System.Text.Encoding.Default.GetBytes(txtMessage.Text);
Int32 len = bytearry.Length;
COPYDATASTRUCT cds;
cds.dwData = 0;        //使用しない
cds.lpData = txtMessage.Text; //テキストのポインターをセット
cds.cbData = len + 1;     //長さをセット
//文字列を送る
result = SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
}

//数値メッセージを送信します
if (txtInt1.Text != string.Empty && txtInt2.Text != string.Empty)
{
Int32 int1 = 0;
Int32 int2 = 0;
try
{
//数値に正しく変換出来るか?
int1 = int.Parse(txtInt1.Text);
int2 = int.Parse(txtInt2.Text);
}
catch
{
MessageBox.Show("入力された数値が正しく有りません");
return;
}
//数値を送る
result = SendMessage(hWnd, WM_USER, int1, int2);
}
}
VB.NET コード
    '送信ボタン押下
Private Sub butSend_Click(ByVal sender As System.Object,  _
ByVal
e As System.EventArgs) Handles butSend.Click
Dim result As Int32 = 0

'相手のウィンドウハンドルを取得します
Dim hWnd As Int32 = FindWindow(Nothing, txtName.Text)
If hWnd = 0 Then
'ハンドルが取得できなかった
MessageBox.Show("相手Windowのハンドルが取得できません")
Return
End If


'文字列メッセージを送信します
If txtMessage.Text <> String.Empty Then
'送信データをByte配列に格納
Dim bytearry() As Byte = _
System.Text.Encoding.Default.GetBytes(txtMessage.Text)
Dim len As Int32 = bytearry.Length
Dim cds As COPYDATASTRUCT
cds.dwData = 0 '使用しない
cds.lpData = txtMessage.Text 'テキストのポインターをセット
cds.cbData = len + 1 '長さをセット
'文字列を送る
result = SendMessage(hWnd, WM_COPYDATA, 0, cds)
End If

'数値メッセージを送信します
If txtInt1.Text <> String.Empty And txtInt2.Text <> String.Empty Then
Dim int1 As Int32 = 0
Dim int2 As Int32 = 0
Try
'数値に正しく変換出来るか?
int1 = CType(txtInt1.Text, Int32)
int2 = CType(txtInt2.Text, Int32)
Catch
MessageBox.Show("入力された数値が正しく有りません")
Return
End Try
'数値を送る
result = SendMessage(hWnd, WM_USER, int1, int2)
End If
End Sub
画像ファイル