SAK 図書館
VB テクニック編35 - メッセージ送受信処理、RegisterWindowMessage
■SAK 関数利用規程
・テクニック編で紹介する関数は、私こと Y.SAK の開発関数である。
・著作権明示部分の改編は認めない。
・個人、企業がこれらの関数を使用したり、一部を使用して新たなシステムや
プログラムを開発することは自由です。
・但し、これらの関数を一部でも使用しているソフトウェアをシェアウェア、
その他有償プロダクトとして配布・販売するには、私の許可が必要です。
(無償のフリーソフトウェアなら、自由に配布しても良い。)
・これらの関数を使用して発生した、いかなる形での損害も私こと Y.SAK は
賠償しません。
■プログラム間メッセージ送受信処理
・ウィンドウメッセージの WM_USER 域を使用して、別のプログラムウィンド
ウとデータのやり取りをするには、次のようにする。
この例では、C と VB6 プログラム間でメッセージのやり取りをする。
ウィンドウメッセージの共有ID は、RegisterWindowMessage で登録する。
■C 側ウィンドウメッセージ処理
・C 側の処理イメージは、次のようになる。
RegisterWindowMessage は、WM_CREATE などで最初に一度だけ実行する。
・lParam で文字列を送るために少し面倒なループ送受信を行っている。
単純な数値データならもっとシンプルに送受信できる。
尚、この C サンプルは動作テストしてないので注意下さい。
#define UMSG_TEST_START 0
#define UMSG_TEST_CHAR 1
#define UMSG_TEST_END 2
UINT WmUserTest;
HWND hSendWnd;
char msgstr[256];
// 共用ウィンドウメッセージID 登録
WmUserTest = RegisterWindowMessage("WM_USER_TEST");
// データセット
hSendWnd = 送信先 VB ウインドウハンドル;
lstrcpy(msgstr, "VB へメッセージ送信");
// VB へウィンドウメッセージ送信
PostMessage(hSendWnd, WmUserTest, UMSG_TEST_START, NULL);
for (i = 0; i < lstrlen(msgstr); i++) {
PostMessage(hSendWnd, WmUserTest, UMSG_TEST_CHAR, (LPARAM) msgstr[i]);
}
PostMessage(hSendWnd, WmUserTest, UMSG_TEST_END, NULL);
/*
========================================================================
ウィンドウプロシジャ
========================================================================
*/
LRESULT CALLBACK _export WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static char rcvmsg[256];
// メッセージ処理
switch (message) {
// VB からの WM_USER_TEST メッセージ受信処理
case WmUserTest:
switch (wParam) {
case UMSG_TEST_START:
// 受信メッセージクリア
lstrcpy(rcvmsg, "");
return(0);
case UMSG_TEST_CHAR:
// 受信メッセージ結合
lstrcat(rcvmsg, (CHAR) lParam);
return(0);
case UMSG_TEST_END:
// 受信メッセージ表示
MessageBox(hWnd, rcvmsg, "UMSG_TEST メッセージ受信", MB_OK | MB_ICONINFORMATION);
return(0);
}
}
// デフォルトメッセージ処理
return(DefWindowProc(hWnd, message, wParam, lParam));
}
■VB 側ウィンドウメッセージ処理
・VB 側の処理イメージは、次のようになる。
RegisterWindowMessage は、Form_Load などで最初に一度だけ実行する。
また、サブクラス化も Form_Load などで最初に一度だけ実行する。
サブクラス解除は、Form_Unload などで最後に一度だけ実行する。
・lParam で文字列を送るために少し面倒なループ送受信を行っている。
単純な数値データならもっとシンプルに送受信できる。
・動作検証サンプルとして、自分自身にメッセージを送信して、受信メッセー
ジを表示するプログラムを添付しておく。
サブクラス化ウィンドウメッセージ処理サンプル subcluss.lzh 2,673 bytes
Public Const UMSG_TEST_START = 0
Public Const UMSG_TEST_CHAR = 1
Public Const UMSG_TEST_END = 2
Public Const GWL_WNDPROC = -4
Public WmUserTest As Long
Public hSendWnd As Long
Public OldWndProc As Long
Dim msgstr As String
Dim i As Long
'** 共用ウィンドウメッセージID 登録
WmUserTest = RegisterWindowMessage("WM_USER_TEST")
'** サブクラスコントロール開始
OldWndProc = GetWindowLong(HWND, GWL_WNDPROC)
SetWindowLong HWND, GWL_WNDPROC, AddressOf WndProc
'** データセット
hSendWnd = 送信先 C ウインドウハンドル
msgstr = "C へメッセージ送信"
'** C へウィンドウメッセージ送信
PostMessage hSendWnd, WmUserTest, UMSG_TEST_START, 0
For i = 1 To Len(msgstr)
PostMessage hSendWnd, WmUserTest, UMSG_TEST_CHAR, Asc(Mid(msgstr, i, 1))
Next
PostMessage hSendWnd, WmUserTest, UMSG_TEST_END, 0
'** サブクラスコントロール終了
SetWindowLong HWND, GWL_WNDPROC, OldWndProc
'=======================================================================
' ウィンドウプロシジャ
'=======================================================================
Public Function WndProc(ByVal hwindow As Long, ByVal message As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Static rcvmsg As String
'** メッセージ処理
Select Case message
Case WmUserTest
Select Case wParam
Case UMSG_TEST_START
'** 受信メッセージクリア
rcvmsg = ""
WndProc = 0
Exit Function
Case UMSG_TEST_CHAR
'** 受信メッセージ結合
rcvmsg = rcvmsg & Chr(lParam)
WndProc = 0
Exit Function
Case UMSG_TEST_END
'** 受信メッセージ表示
MsgBox rcvmsg, 64, "UMSG_TEST メッセージ受信
WndProc = 0
Exit Function
End Select
End Select
'** デフォルトメッセージ処理
WndProc = CallWindowProc(OldWndProc, hwindow, message, wParam, lParam)
End Function
Private Declare Function RegisterWindowMessageA Lib "user32" (ByVal msgid As String) As Long
Private Declare Function RegisterWindowMessageW Lib "user32" (ByVal msgid As String) As Long
'=======================================================================
' Windows API RegisterWindowMessage()
'=======================================================================
Public Function RegisterWindowMessage(msgid As String) As Long
If GetOS() = VER_PLATFORM_WIN32_NT Then
RegisterWindowMessage = RegisterWindowMessageW(msgid)
Else
RegisterWindowMessage = RegisterWindowMessageA(msgid)
End If
End Function
■VB テクニック編資料
■VB 入門編資料
■VB 基礎編資料
■VB ビジュアル編資料