2010-12-20 74 views
1

我正在尝试将一个包装器写入一个服务,该服务将由现有的VB6项目使用。除了一个重要的方面,我已经掌握了大部分基础框架:除了一个重要的方面:我可以在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类'' – 2010-12-20 16:56:53

+0

@Hans:我创建了类库项目,删除了默认类,然后添加了一个新项目,并从选项中选择了“COM类”。 – Antagony 2010-12-20 17:25:40

+0

我不得不直接使用来使事件正常工作。我+虽然+ 会自动做到这一点,但它似乎并没有这样工作。 – DarinH 2010-12-20 22:49:50

回答

7

它太多的评论写的,所以我会让它的答案....

首先,确定你希望暴露给COM .NET类。我将选择一个名为CORE的课程。

创建一个描述CORE对象将源(即生成)的事件的接口。

<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 

,创建您的实际.NET类

<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 

现在,当你需要从你的类内提高FileLoaded事件,刚刚的RaiseEvent FILELOADED(消息)。 .NET将把事件转发给COM,因为你已经连接了COMSourceInterfaces属性。

该属性是其中大部分内容的简写,但不幸的是,它不能完全控制您需要做某些事情(例如在您的com接口上保留版本兼容性)。

+0

感谢您的详细解答,我创建了一个新项目来测试它。不幸的是,似乎存在一个问题:“实现ICore”行为属性产生错误 - 类'Core'必须为接口'ICore'实现'ReadOnly Property Name As String'。实现属性必须具有匹配的“ReadOnly”或“WriteOnly”说明符。我自己尝试了一些东西,但没有明显的解决方案涌向我。 – Antagony 2010-12-21 18:37:22

+0

我几乎在那里,我想,drventure。因为我复制并粘贴了你的代码,VB没有在Core类中创建相应的属性 - 我只需要在Implements行上返回并解决了这个问题。 D'哦! – Antagony 2010-12-21 19:24:23

+0

现在,我已经构建了该类,并使用regasm将其注册为一个tlb文件。该类显示在VB6测试项目中,就事件,方法和属性而言,一切都看起来没问题 - 它们都在IDE中正确显示 - 但只要我尝试创建新实例的类我得到一个自动化错误:“系统找不到指定的文件。”这似乎很奇怪,因为似乎没有任何文件被引用到代码中的任何地方。 – Antagony 2010-12-21 19:24:46