ホーム > API, Visual Basic > VB6でプロセス間通信

VB6でプロセス間通信

実行環境: Windows7 Pro / Visual Basic 6


Delphiでは普通にやってたことですが、VB6でプロセス(アプリケーション)間の通信をする必要があったので、ここにその方法を記録。
ウィンドウメッセージによるプロセス間通信するには、次のような定義が必要となる。

  • ウィンドウプロシージャサブクラス化する
  • プロセス間で固有のウィンドウメッセージを定義する
  • プロセス間で固有のキーワードを定義する
  • そのウィンドウメッセージで使用するパラメータを定義する

プロセス間でウィンドウメッセージを共有するためにWM_APPWM_USERではなく、より安全なRegisterWindowMessageを使っている。

ウィンドウプロシージャサブクラス化を利用しているプロジェクトをVB6IDEからデバッグする場合の注意点。

  • デバッグ中は、IDEをマウスで操作できなくなる
  • イミディエイトウィンドウへフォーカスが移せない
  • IDEから中断終了するとVB6クラッシュする

VB6で作られたアプリケーションのトップレベルウィンドウを探す場合、ウィンドウクラス(ThunderRT6FormDC)が固定になってしまうので、ウィンドウキャプションでしか探せない点にも注意が必要。


AppMain.frm

Public Property Let IsAppSubStarted(Value As Boolean)
    If Value Then
        MsgBox ("サブアプリケーションが起動した")
    End If
End Property

Public Property Let IsAppSubClosing(Value As Boolean)
    If Value Then
        MsgBox ("サブアプリケーションが終了する")
    End If
End Property

Public Property Let AppSubStatus(Value As Long)
    ' 何かの処理
End Property

Private Sub Form_Initialize()
    WmSharingID = RegisterWindowMessage(WM_SHARING_ID)

    ' Hook時のMe.hWndの値 と UnHook時のMe.hWndの値 が異なることが想定されるため、変数(GHWND)を用意している
    GHWND = Me.hWnd
    OriginalWndProc = AppHook(GHWND)
End Sub

Private Sub Form_Load()
On Error GoTo Error_Sub
    
Exit_Sub:
    hSendWnd = FindWindow(vbNullString, WC_APP_SUB)
    Call PostMessage(hSendWnd, WmAlcSharingID, UMSG_APP_MAIN_START, 0)
    Exit Sub
Error_Sub:
    Call Logging.ErrorLog(Err.Description)
End Sub

Private Sub Form_Unload(Cancel As Integer)
On Error GoTo Error_Sub
    
Exit_Sub:
    hSendWnd = FindWindow(vbNullString, WC_APP_SUB)
    Call PostMessage(hSendWnd, WmSharingID, UMSG_APP_MAIN_CLOSE, 0)
    Exit Sub
Error_Sub:
    Call Logging.ErrorLog(Err.Description)
End Sub

Private Sub Form_Terminate()
    Call AppUnHook(GHWND)
End Sub

sample.bas

Public Const GWL_WNDPROC = -4

' アプリケーション(プロセス)間通信用Keyword
Public Const WM_SHARING_ID = "HOGE HOGE HOGE"
' メインアプリケーションのウィンドウキャプション
Public Const WC_APP_MAIN = "Main Application"
' サブアプリケーションのウィンドウキャプション
Public Const WC_APP_SUB = "Sub Application"

' メインアプリケーションが起動した時のパラメータ(wParam)
Public Const UMSG_APP_MAIN_START = &H1001
' メインアプリケーションが終了する時のパラメータ(wParam)
Public Const UMSG_APP_MAIN_CLOSE = &H1002
' メインアプリケーションが通知してくるステータス(lParam)
Public Const UMSG_APP_MAIN_STATUS = &H1003

' サブアプリケーションが起動した時のパラメータ(wParam)
Public Const UMSG_APP_SUB_START = &H2001
' サブアプリケーションが終了する時のパラメータ(wParam)
Public Const UMSG_APP_SUB_CLOSE = &H2002
' サブアプリケーションが通知してくるステータス(lParam)
Public Const UMSG_APP_SUB_STATUS = &H2003

Public WmSharingID As Long
Public OriginalWndProc As Long
Public hSendWnd As Long
Public GHWND As Long

Private Declare Function SetWindowLongW Lib "user32" (ByVal hwd As Long, ByVal nIndex As Long, ByVal Dt As Long) As Long
Private Declare Function CallWindowProcW Lib "user32" (ByVal oldproc As Long, ByVal hwd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function RegisterWindowMessageW Lib "user32" (ByVal msgid As String) As Long
Private Declare Function PostMessageW Lib "user32" (ByVal hwd As Long, ByVal Msg As Long, ByVal wpara As Long, ByVal lpara As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Public Function RegisterWindowMessage(msgid As String) As Long
    RegisterWindowMessage = RegisterWindowMessageW(msgid)
End Function

Public Function AppHook(vHWND As Long) As Long
    AppHook = SetWindowLong(vHWND, GWL_WNDPROC, AddressOf WndProc)
End Function

Public Function AppUnHook(vHWND As Long) As Long
    AppUnHook = SetWindowLong(vHWND, GWL_WNDPROC, OriginalWndProc)
    OriginalWndProc = 0
End Function

' サブクラス化しているため VB6 の IDE デバッグ中は、次の点に注意。
'   ・イミディエイトウィンドウが利用できない
'   ・マウス操作で VB6 の IDE を操作できない
'   ・VB6 の IDE メニューの "終了"・"停止" をすると、オリジナルのウィンドウプロシージャに切り替わらず終わるため IDE がクラッシュする!!!!
Public Function WndProc(ByVal vHWND As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
On Error GoTo Error_Sub

    Static BufChr As String

    Select Case Msg
    Case WM_NCDESTROY
        Call AppUnHook(vHWND)
    
    ' カスタムウィンドウメッセージ
    Case WmSharingID
        Select Case wParam
        Case UMSG_APP_MAIN_START
            ' メインアプリケーション(AppMain.exe)が起動した時のイベント(処理)を記述
            FrmAppSub.IsAppMainStarted = True
        Case UMSG_APP_MAIN_CLOSE
            ' メインアプリケーション(AppMain.exe)が終了する時のイベント(処理)を記述
            FrmAppSub.IsAppMainClosing = True
        Case UMSG_APP_MAIN_STATUS
            ' メインアプリケーション(AppMain.exe)が通知してくるステータスのイベント(処理)を記述
            FrmAppSub.AppMainStatus = lParam
        Case UMSG_APP_SUB_START
            ' サブアプリケーション(AppSub.exe)が起動した時のイベント(処理)を記述
            FrmAppMain.IsAppSubStarted = True
        Case UMSG_APP_SUB_CLOSE
            ' サブアプリケーション(AppSub.exe)が終了する時のイベント(処理)を記述
            FrmAppMain.IsAppSubClosing = True
        Case UMSG_APP_SUB_STATUS
            ' サブアプリケーション(AppSub.exe)が通知してくるステータスのイベント(処理)を記述
            FrmAppMain.AppSubStatus = lParam
        Case Else
            Call Logging.WarnLog("wParam: " & wParam & " は、定義されていないパラメータです。")
        End Select
    Case Else
    End Select

Exit_Sub:
    WndProc = CallWindowProc(OriginalWndProc, vHWND, Msg, wParam, lParam)
    Exit Function
    
Error_Sub:
    Call Logging.ErrorLog(Err.Description)
    WndProc = CallWindowProc(OriginalWndProc, vHWND, Msg, wParam, lParam)
End Function

Public Function SetWindowLong(hwd As Long, nIndex As Long, Dt As Long) As Long
    SetWindowLong = SetWindowLongW(hwd, nIndex, Dt)
End Function

Public Function CallWindowProc(ByVal oldproc As Long, ByVal hwd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    CallWindowProc = CallWindowProcW(oldproc, hwd, Msg, wParam, lParam)
End Function

APIで学ぶWindows徹底理解―できるプログラマになるための (日経BPパソコンベストムック)

中古価格
¥2,190から
(2012/11/16 14:40時点)

APIで学ぶWindowsプログラミング (日経BPパソコンベストムック)

新品価格
¥2,520から
(2012/11/16 14:41時点)

Microsoft Visual Basic 6.0 Professional Edition

中古価格
¥69,800から
(2012/11/16 14:42時点)

Microsoft Visual Studio Professional 2012 通常版

新品価格
¥55,545から
(2012/11/16 14:45時点)

About these ads
カテゴリー:API, Visual Basic
  1. コメントはまだありません。
  1. No trackbacks yet.

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。