【PC】VB6 から VB2010 への移行(その3)プロセス間通信(送信)
過去の資産としてVisual Basic 6 のものがあったとして、全システムを一気に .NET(Visual Studio 2010)まで持っていければ一番いいのだろうけれども、費用や時間の問題からなかなかそうは出来ないケースもある。
そんなとき、筆者は、とくに変更したい一部(変更しなくてはならない一部)を、またもや VB6を引っ張り出して書き直すのではなく、将来的なことも考えて VB2010 で書くことにしている。このとき完全に独立したプロセス(プログラム)なら Shell() で呼び出せばそれでおわりだが、VB6のプロセスと VB2010 のプロセスで何らかの連絡や共有を行いたい場合がある。
一番簡単な共有はファイルだが速度に問題がありそうだ。次の選択肢としてはメモリマップトファイル(MMF)で”共有メモリ”を使う方法で VB2010(.NET Freamwork 4)なら元から MMF のクラスもあって取り扱いも容易だ。
しかしながら何らかの連絡を行いたい場合には、どちらもタイマーで値の変更を監視したりしなければならず、けっこうなリソースを食ってしまう。実際にやってみたが、ややもたつきを感じるくらいには速度も落ちる。
そこで筆者は、窓から窓にメッセージを投げつける PostMessage を使うことにしている。
メッセージの受信は少々ややこしいが、送信はカンタン。
VB6 の場合
Private Declare Function FindWindow _ Lib "user32" Alias "FindWindowW" _ (ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long Private Declare Function PostMessage _ Lib "user32" Alias "PostMessageW" _ (ByVal hwd As Long, _ ByVal msg As Long, _ ByVal wpara As Long, ByVal lpara As Long) As Long const pmSTART = &h0 const pmDATA = &h1 const pmEND = &h2 Public Sub VB6から送信(Str As String) Dim hSend As Long Dim c as string Dim I as integer hSend = FindWindow(vbNullString, "相手のプロセスの窓の名前") If hSend <> 0 Then 'メッセージ送信開始 PostMessage hSend,"適当な共有名",pmSTART, 0 '文字列の送信 For I = 1 To Len(Str) c = Mid(Str, I, 1) PostMessage hSend,"適当な共有名",pmDATA, Asc(c) Next 'メッセージ送信終了 PostMessage hSend,"適当な共有名",pmEND, 0 End If End Sub
というような感じ。
APIのFindWindowで、メッセージを送りたい相手の窓の名前からハンドルを取得。そこに PostMessageでメッセージを投げつけている。
Const で定義した pmSTART や pmDATA は 勝手ルール。受信側でこのルールに基づいて処理をして受け取るようにする。この場合 VB6 から VB2010 へ投げつけているので、受信の処理は VB2010 側に記述することになる。
VB2010 の場合(ほぼ同じ・・・というか全く同じ(笑))
_ Private Function FindWindow( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As IntPtr End Function _ Public Function PostMessage( _ ByVal hwd As IntPtr, _ ByVal msg As IntPtr, _ ByVal wpara As IntPtr, _ ByVal lpara As IntPtr) As IntPtr End Function const pmSTART = &h0 const pmDATA = &h1 const pmEND = &h2 Public Sub VB2010から送信(Str As String) Dim I As Integer Dim c as string 'ハンドル取得 Dim hWnd As Int32 = FindWindow(Nothing,"VB6の窓の名前") If hWnd <> 0 Then 'メッセージ送信開始 PostMessage(hWnd,"適当な共有名",pmSTART, 0) '文字列の送信 For I = 0 To Str.Length - 1 c = Str.Substring(I, 1) PostMessage(hWnd,"適当な共有名",pmDATA,Asc(c)) Next 'メッセージ送信終了 PostMessage(hWnd,"適当な共有名",pmEND, 0) End If End Sub
これで VB6 へメッセージを投げつけることができる。
あとは「受信」をそれぞれに用意するが「そういう仕掛けをつくる」のはちょっとややこしい。これは次回。