2010-12-20 6 views
1

私は、既存のVB6プロジェクトで使用されるサービスへのラッパーを作成しようとしています。私は、基本的なフレームワークのほとんどが1つの重要な側面を除いて動作している:私はVB6のプロジェクトでラッパーを参照することができます/サブ関数呼び出しなど期待どおりに動作しますが、イベントはありません。イベントはVB6アプリケーションで表示されますが、決して起動しません。COMに公開されているクラスライブラリのイベントを発生

VB.NETコード:

Public Event Action_Response(ByVal Status as String) 
Public Function TestEvent() 
    RaiseEvent Action_Response("Test Done") 
    Return "Done" 
End Function 

VB6コード:だから

Dim WithEvents my_Wrapper as Wrapper_Class 
Private Sub cmdTest_Click() 
    Set my_Wrapper = New Wrapper_Class 
    Debug.Print my_Wrapper.TestEvent() 
End Sub 

Private Sub my_Wrapper_Action_Response(ByVal Status As String) 
    Debug.Print Status 
    Set my_Wrapper = Nothing 
End Sub 

、期待通りcmdTestボタンコードプリントは '完了' が、Action_Responseイベントは発生しません。イベントを開始するために何か他に必要なことはありますか?

+0

あなたのVB.NETクラスの作成方法を文書化してください。

+0

@Hans:クラスライブラリプロジェクトを作成し、デフォルトクラスを削除して新しいアイテムを追加し、オプションから「COMクラス」を選択しました。 – Antagony

+0

イベントを正しく動作させるためには、を直接使用しなければなりませんでした。私は+ + + それを自動的に行いますが、それはそのように動作していないようです。 – DarinH

答えて

7

そのコメントに書くことがあまりので、私はそれ答えてあげる....

まず、あなたがCOMに公開する.NETクラスを識別します。私はCOREというクラスを選びます。

COREオブジェクトがソースとなる(つまり生成する)EVENTSを記述するインタフェースを作成します。

<ComVisible(True)> _ 
<Guid("some guid here...use guidgen, I'll call it GUID1")> _ 
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _ 
Public Interface ICoreEvents 
    <System.Runtime.InteropServices.DispId(1)> _ 
    Sub FileLoaded(ByVal Message As String) 
End Interface 

次に、クラスのCOM公開プロパティとメソッドのインターフェイスを作成します。

<ComVisible(True)> _ 
<Guid("another GUID, I'll call it guid2")> _ 
<InterfaceType(ComInterfaceType.InterfaceIsDual)> _ 
Public Interface ICore 
    ReadOnly Property Property1() As Boolean 
    ReadOnly Property AnotherProperty() As ISettings 
    ReadOnly Property Name() As String 
    ReadOnly Property Phone() As String 
End Interface 

さて、さて、あなたはクラス内からFileLoadedイベント、ちょうどRAISEEVENT FILELOADED(メッセージ)を調達する必要がある場合

<ComVisible(True)> _ 
<ClassInterface(ClassInterfaceType.None)> _ 
<ComDefaultInterface(GetType(ICore))> _ 
<ComSourceInterfaces(GetType(ICoreEvents))> _ 
<Guid("a third GUID, I'll call it GUID3")> _ 
Public Class Core 
    Implements ICore 

    <System.Runtime.InteropServices.ComVisible(False)> _ 
    Public Delegate Sub OnFileLoaded(ByVal Message As String) 
    Public Event FileLoaded As OnFileLoaded 
End Class 

実際の.NETクラスを作成します。 COMSourceInterfaces属性を接続しているため、.NETはイベントをCOMに転送します。

この属性の大部分は簡略化していますが、残念ながら、特定のことを行う必要がある(たとえば、お使いのCOMインターフェイスでのバージョンの互換性を維持するなど)必要はありません。

+0

詳細な回答をありがとう、私はそれをテストするための新しいプロジェクトを作成しました。残念ながら、 "ICoreを実装する"行がプロパティのエラーを発生させています。クラス 'Core'は、 'ICore'インタフェースの 'ReadOnly Property Name As String'を実装する必要があります。プロパティの実装には、 'ReadOnly'または 'WriteOnly'指定子が一致している必要があります。私はいくつか自分で試しましたが、明らかな解決策は私には出ていません。 – Antagony

+0

私はほぼそこにいると思います。私はあなたのコードをコピーして貼り付けていたので、VBはCoreクラスの対応するプロパティを作成していませんでした - 私はImplements行のリターンをヒットしなければなりませんでした。 D'oh! – Antagony

+0

今、私はクラスを構築し、regasmを使ってtlbファイルで登録しました。 VB6テストプロジェクトでクラスが表示されていますが、イベント、メソッド、プロパティに関する限り、すべてが問題なく表示されます。これらはIDEで正しく表示されますが、新しいインスタンスを作成しようとするとすぐに私はオートメーションエラーが発生しているクラスの: "システムが指定されたファイルを見つけることができません。コード内のどこにでも参照されるファイルがないように思われるので、奇妙に思えます。 – Antagony

関連する問題