Partilhar via


VBマイグレーション3

こんにちは、こだかです。

更に引き続きVBマイグレーションの話です。
今回は部分移行として、COMクライアントからマネージクラインアントの利用を紹介します。
肥大したVBプロジェクトは、一気に移行することが難しい場合も多いと思います。
少しづつ.NETに移行していく手法は、十分に検討の余地があるはずです。

COMクライアントからマネージクラインアントを利用する場合、内部でCLRがCCW(COM Callable Wrapper) を作成して動作します。
やることは非常に単純で、単にVisualStudioでコンパイルする際、[プロジェクトの右クリック]→[プロパティ]→[コンパイル]→[COMの相互運用機能の登録]にチェックを入れておくだけです。
こうすると、作成されたアセンブリと一緒に.tlb(タイプライブラリ)が作成されるので、VB6.0の参照設定で登録してあげると、VB6.0から使用可能になります。

(この辺りはMSDNで確認して頂ければと思います。
 https://msdn2.microsoft.com/ja-jp/library/ms172270(VS.80).aspx

ただし、.NET側から発生されたイベントをCOMで受信したい場合には、単にDelegateするだけでは使用できません。
下記のようにInterfaceTypeAttribute属性を指定したInterfaceとComSourceInterfaces属性を指定したクラスが必要になります。
結構面倒ですね。

.NET(Visual Basic)
Public Delegate Sub ClickDelegate(x As Integer, y As Integer)
   
<InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface ButtonEvents
Sub Click(x As Integer, y As Integer)
End Interface

   
<ComSourceInterfaces(GetType(ButtonEvents))> _
 Public Class Button
Public Event Click As ClickDelegate
      
     Public Sub CauseClickEvent(x As Integer, y As Integer)
         RaiseEvent Click(x, y)
     End Sub
 End Class

COMクライアント
Public WithEvents myButton As Button

Private Sub myButton_Click(ByVal x As Long, ByVal y As Long)
    MsgBox "Click event"
End Sub

Private Sub Form_Load()
    Set myButton = New Button 
    Call myButton .CauseClickEvent(1, 2)
End Sub

このシナリオを比較的単純にする、Microsoft提供のCOM相互運用のアドインがあります。
Microsoft Interop Forms Toolkit 1.0
https://msdn2.microsoft.com/en-us/vbasic/aa701259

こちらを使用する例を紹介しましょう。
プロジェクトの新規作成を選択すると、「VB6InteropFormLibraly」が追加されているはずです。
選択して実行すると、Formが1つ出来ます。
イベント公開のサンプルは、以下のように書くことができます。
属性は必要ですが、普通にDelegateするだけです。

.NET(Visual Basic)
Imports Microsoft.InteropFormTools
<InteropForm()> _
Public Class InteropForm1
    Public Delegate Sub ClickDelegate(ByVal x As Integer, ByVal y As Integer)
<InteropFormEvent()> _
Public Event Click As ClickDelegate

    <InteropFormMethod()> _
    Public Sub CauseClickEvent(ByVal x As Integer, ByVal y As Integer)
        RaiseEvent Click(x, y)
    End Sub
End Class

次に、ツールからGenerate InteropForm Wrapper Classesを実行します。
(無い場合はアドインマネージャーから追加して下さい。)
ビルドすると.tlbができるので、あとはVB6.0側で利用すればOKです。

VB6.0側では、上記のタイプライブラリとMicrosoft Interop Forms Toolkit Libraryの参照設定を行い、
以下のようなソースを書きます。

COMクライアント
Public g_InteropToolbox As InteropToolbox
Private WithEvents MyForm As Test.InteropForm1

Private Sub Form_Load()
    Set g_InteropToolbox = New InteropToolbox
    g_InteropToolbox.Initialize
    g_InteropToolbox.EventMessenger.RaiseApplicationStartedupEvent
    Set MyForm = New Test.InteropForm1
    Call MyForm.CauseClickEvent(1, 2)
End Sub

Private Sub MyForm_Click(ByVal x As Long, ByVal y As Long)
    MsgBox "Click event"
End Sub

上記の.NET側のソースは、見ていただければ分るように、幾つかの属性があります
これは、Interop Forms Toolkitから提供される属性で、COMに公開したいForm、メソッド、プロパティ、イベント、イニシャライズメソッドには、それぞれ以下の属性をつける必要があります。
InteropForm()
InteropFormMethod()
InteropFormProperty()
InteropFormEvent()
InteropFormInitializer()

とは言え、割と.NET(Visual Basic)側のソースが単純になりました。
個人的には、これはVB6.0側でActiveXExe、ActiveXDllとして作成し、マネージ、アンマネージの橋渡しは1ファイル(実際はマネージ、アンマネージで2ファイルですが。)で行うことをお勧めしたいです。

このような例も、マイグレーションの手法の一つとして、認識して頂けると幸いです。

マイグレーションに関しては以下のサイトに情報がありますので、ご確認頂けるとよいかもしれません。
(参照:https://www.microsoft.com/japan/msdn/vbasic/migration/

以上です。

こだかたろう