ActiveX.EXEでイベントを発生させ、VB.NETで受け取るには?

解決


まご  2010-06-23 20:07:09  No: 102432

はじめて投稿させて頂きます。
VB6にてActiveX EXE を作成し、そこでRaiseEventを発行しております。
このイベントを、VB.NET(初めはVB6の標準EXEでも可)にて受け取りたいのですが、どのようにしたら良いのでしょうか?

過去ログに解決済みの似たような質問がございましたが、上手く動作させることが出来なかったため、質問させて頂きました。

また、全く同じソースコードでも、「ActiveX DLL」の場合は、VB6の標準EXEと正常に連携動作しております。
(ただし、VB.NETで連携しようとすると、Formを表示することは出来ない旨のエラーとなってしまいます。このため「ActiveX EXE」で作成しようと思いました)

簡単なソースを下記致します。

【ActiveX EXE】
1つのクラスと、1つのFormから出来ております。

1)クラス(仮にTestClass)
'イベント定義
Public Event CallingEvent(ByVal str1 As String, _
                          ByVal str2 As String, _
                          ByVal str3 As String, _
                          ByVal str4 As String)

Private WithEvents testForm As TestForm

'Formオープン処理(MTMW開始処理をForm側で行う)
Public Sub openForm()
    Set testForm = New TestForm
    testForm.Show
End Sub

'Formからのイベント
Private Sub testForm_CallingEventForm(ByVal str1 As String, _
                                       ByVal str2 As String, _
                                       ByVal str3 As String, _
                                       ByVal str4 As String)
    'そのまま再度イベント発行
    RaiseEvent CallingEvent(str1, str2, str3, str4)
    'このイベント発行が、VB.NET(またはVB6の標準EXE)に飛ばないです
    'ここまで処理が来ていることは確認済みです
End Sub

'Formクローズ処理
Public Sub closeForm()
    'Formクローズ
    Call Unload(testForm)
End Sub

2)Form(仮にTestForm)
'イベント定義
Public Event CallingEventForm(ByVal str1 As String, _
                              ByVal str2 As String, _
                              ByVal str3 As String, _
                              ByVal str4 As String)

'イベント処理
Private Sub AAA_BBB()
    '色々処理
    'イベント発行
    RaiseEvent CallingEventForm(str1, str2, str3, str4)
    'このイベント発行は上手く動作しています
End Sub

【VB.NET側処理】
Public Class TestForm2
  Private WithEvents testClass As TestProject.TestClass = New TestProject.TestClass

  Private Sub FrmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    '色々処理
    testClass.openForm()
    'この処理は成功します
  End Sub

  Private Sub frmMain_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
    '色々処理
    testClass.closeForm()
    'この処理も成功します
  End Sub

  Private Sub CCC(ByVal str1 As String, _
                  ByVal str2 As String, _
                  ByVal str3 As String, _
                  ByVal str4 As String) Handles testClass.CallingEvent
    'ここのイベントが受信できません
  End Sub
End Class

どこに過ちがあるのか、ご教示頂ければ幸いです。


魔界の仮面弁士  2010-06-24 05:23:42  No: 102433

> 上手く動作させることが出来なかったため、質問させて頂きました。
ActiveX 側の「バージョン間の互換性」を、バイナリ互換にしていますか?

> Private WithEvents testForm As TestForm
実際のコードは、どのようになっているのでしょうか?

コピー & ペーストしたコードなら、
Private WithEvents testForm As testForm か
Private WithEvents TestForm As TestForm になっているはず…。

> Public Class TestForm2
>    Private Sub FrmMain_Load(…) Handles MyBase.Load
>    Private Sub frmMain_FormClosed(…) Handles Me.FormClosed
TestForm2 に対するイベントハンドラのプレフィックスが
FrmMain や frmMain になっているのは、意図的なものでしょうか?

# Handles が MyBase だったり Me だったりするのは仕方ないですが。

> このイベントを、VB.NET(初めはVB6の標準EXEでも可)にて受け取りたいのですが、
> どのようにしたら良いのでしょうか?
提示のコードで、VB6 の標準EXE から、何の問題も無く呼べましたので、
提示していない部分に問題があるのでは無いでしょうか。

一応、こちらの検証コードを載せておきます。

'★★★ VB6 ActiveX EXE [TestProject] (スタートモード= ActiveX コンポーネント)
'*** フォーム TestForm (ボタン Command1 を用意)
Option Explicit
Public Event CallingEventForm(ByVal str1 As String, ByVal str2 As String, ByVal str3 As String, ByVal str4 As String)
Private Sub AAA_BBB()
    RaiseEvent CallingEventForm("str1", "str2", "str3", "str4")
End Sub
Private Sub Command1_Click()
    AAA_BBB
End Sub

'*** クラス TestClass (Instancing = MultiUse)
Option Explicit
Public Event CallingEvent(ByVal str1 As String, ByVal str2 As String, ByVal str3 As String, ByVal str4 As String)
Private WithEvents TestForm As TestForm  '本来は、別名にした方が無難
Public Sub openForm()
    Set TestForm = New TestForm
    TestForm.Show  'Call 無しのメソッド呼び出し
End Sub
Private Sub TestForm_CallingEventForm(ByVal str1 As String, ByVal str2 As String, ByVal str3 As String, ByVal str4 As String)
    RaiseEvent CallingEvent(str1, str2, str3, str4)
End Sub
Public Sub closeForm()
    Call Unload(TestForm)  'Call 付きのメソッド呼び出し
End Sub

'★★★ VB6 標準 EXE [Project1] (TestProject.exe を参照設定)
'*** フォーム Form1
Option Explicit
Private WithEvents TestClass As TestProject.TestClass
Private Sub Form_Load()
    Set TestClass = New TestProject.TestClass
    TestClass.openForm
End Sub
Private Sub Form_Unload(Cancel As Integer)
    TestClass.closeForm
End Sub
Private Sub TestClass_CallingEvent(ByVal str1 As String, ByVal str2 As String, ByVal str3 As String, ByVal str4 As String)
    MsgBox str1 & vbCrLf & str2 & vbCrLf & str3 & vbCrLf & str4, vbInformation
End Sub

'★★★ VB2008 WinForm アプリ [WindowsApplication1] (TestProject.exe を参照設定)
'*** フォーム TestForm2
Public Class TestForm2
    Private WithEvents testClass As TestProject.TestClass = New TestProject.TestClass
    Private Sub FrmMain_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        testClass.openForm()
    End Sub
    Private Sub frmMain_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        testClass.closeForm()
    End Sub
    Private Sub CCC(ByVal str1 As String, ByVal str2 As String, ByVal str3 As String, ByVal str4 As String) Handles testClass.CallingEvent
        MsgBox(str1 & vbCrLf & str2 & vbCrLf & str3 & vbCrLf & str4, vbInformation)
    End Sub
End Class

蛇足ですが、VB.NET から ActiveX コンポーネントのイベントを利用する場合は、
WithEvents を使うのではなく AddHandler / RemoveHandler を用いた方が、
ReleaseComObject しやすくなります(自動解放に任せるなら WithEvents で充分ですが)。


まご  2010-06-24 20:53:56  No: 102434

コードを記載して頂いて、ありがとうございました。
頂いたコードを試しに動かしてみたところ、正常に動作させることが出来ました。

>ActiveX 側の「バージョン間の互換性」を、バイナリ互換にしていますか?
バイナリ互換にし忘れておりました。

>> Private WithEvents testForm As TestForm
>実際のコードは、どのようになっているのでしょうか?
申し訳ございません。実際のコードでは、変数名とForm名は完全に別物です。
ここに書き込む際に、適当な名称に変更してしまったため、混乱を招いてしまったことをお詫び致します。

>> Public Class TestForm2
>>    Private Sub FrmMain_Load(…) Handles MyBase.Load
>>    Private Sub frmMain_FormClosed(…) Handles Me.FormClosed
>TestForm2 に対するイベントハンドラのプレフィックスが
>FrmMain や frmMain になっているのは、意図的なものでしょうか?
こちらも、書き込む際に適当な名称に変更してしまいました。申し訳ございません。

頂いたコードを元にして、再度、ActiveX EXEでのイベント発行にチャレンジしてみます。
大変ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加