在VB6代码中处理VB.NET事件 [英] Handling VB.NET events in VB6 code

查看:85
本文介绍了在VB6代码中处理VB.NET事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些VB6代码实例化一个处理从VB.NET组件引发的事件的类。 VB6非常简单:

  private m_eventHandler作为新集合

...

public sub InitSomething()
dim handler作为EventHandler

set handler = new EventHandler
m_eventHandler.Add handler
...
m_engine 。开始

end sub

请注意,事件处理程序对象必须生活超出了init方法的范围(这就是为什么它被存储在Collection中)。还请注意, m_engine.Start 表示程序中VB.NET组件将开始提高事件的点。



实际的事件处理程序(根据请求):

  Private WithEvents m_SomeClass As SomeClass 
私有m_object作为对象
...

Private Sub m_SomeClass_SomeEvent(obj As Variant)
设置obj = m_object
End Sub
EventHandler 的实例是 m_object 被初始化创建。



引发事件的VB.NET代码更简单:

  Public ReadOnly Property SomeProp()As Object 
Get
Dim obj As Object
obj = Nothing
RaiseEvent SomeEvent(obj)
SomeProp = obj
结束获取
结束属性

我的问题是,当我调试 VB6程序,第一次 InitSomething 被调用,事件将被处理(VB6事件处理程序从不输入)。随后调用 InitSomething 可以正常工作。



一切都正常运行,当我在调试器外部运行程序。在这一点上,我甚至不确定这是我应该担心的事情。



它可能与也可能并不相关,但是VB.NET被转换为一个VB6使用Visual Studio代码转换工具(并随后手动清理)。

解决方案

我发现如果你是编写.Net在VB6(或任何其他COM环境)中的消耗组件使用接口是绝对关键的。



与VStudio一起出现的COM模板离开很多都是需要的,特别是当你试图让事件工作时。



这是我使用的。

 导入System.Runtime.InteropServices 
导入System.ComponentModel

< InterfaceType(ComInterfaceType.InterfaceIsDual),Guid(ClientAction.InterfaceId)> ;公共接口IClientAction
< DispId(1),描述(使系统引发事件)> sub SendMessage(ByVal theMessage As String)
结束接口


< InterfaceType(ComInterfaceType.InterfaceIsIDispatch),Guid(ClientAction.EventsId)>公共接口IClientActionEvents
< DispId(1)> Sub TestEvent(ByVal sender As Object,ByVal e As PacketArrivedEventArgs)
结束接口



< ComSourceInterfaces(GetType(IClientActionEvents)),Guid(ClientAction.ClassId ),ClassInterface(ClassInterfaceType.None)> _
公共类ClientAction
实现IClientAction

公共委托Sub TestEventDelegate(ByVal sender As Object,ByVal e As PacketArrivedEventArgs)

公共事件TestEvent作为TestEventDelegate

public sub New()
// Init etc
end sub

public sub SendMessage(theMessage as string)实现IClientAction.SendMessage
onSendMessage(theMessage)
end sub

受保护的子onSendMessage(消息作为字符串)
如果mRaiseEvents然后
RaiseEvent TestEvent(Me,New PacketArrivedEventArgs(theMessage))
结束If
End Sub

end Class

我已经能够让Assembly / Component的COM和.Net消费者正确地处理事件,并且可以调试进出组件。



希望这有助于。


I have some VB6 code that instantiates a class which handles events that are being raised from a VB.NET component. The VB6 is pretty straightforward:

private m_eventHandler as new Collection

...

public sub InitSomething()
  dim handler as EventHandler

  set handler = new EventHandler
  m_eventHandler.Add handler
  ...
  m_engine.Start

end sub 

Note that the event handler object has to live beyond the scope of the init method (which is why it is being stored in a Collection). Note also that m_engine.Start indicates the point in the program where the VB.NET component would start raising events.

The actual event handler (as requested):

Private WithEvents m_SomeClass As SomeClass
Private m_object as Object
...

Private Sub m_SomeClass_SomeEvent(obj As Variant)
    Set obj = m_object
End Sub

Note that m_object is initialized when an instance of EventHandler is created.

The VB.NET code which raises the event is even simpler:

Public ReadOnly Property SomeProp() As Object
    Get
        Dim obj As Object
        obj = Nothing
        RaiseEvent SomeEvent(obj)
        SomeProp = obj
    End Get
End Property

My problem is that when I debug the VB6 program, the first time InitSomething gets called, the event will not be handled (the VB6 event handler is never entered). Subsequent calls to InitSomething does work.

Everything works as I would have expected when I run the program outside the debugger. At this point, I'm not even sure if this is something I should be worried about.

It may or may not be relevant but the VB.NET was converted from a VB6 using the Visual Studio code conversion tool (and subsequently manually cleaned up).

解决方案

I've found that if you are writing .Net Components for Consumption in VB6 (or any other COM environment) the utilisation of Interfaces is absolutely criticial.

The COM templates that comes out of the box with VStudio leave a lot to be desired especially when you are trying to get Events to work.

Here's what I've used.

Imports System.Runtime.InteropServices
Imports System.ComponentModel

<InterfaceType(ComInterfaceType.InterfaceIsDual), Guid(ClientAction.InterfaceId)> Public Interface IClientAction
        <DispId(1), Description("Make the system raise the event")> sub SendMessage(ByVal theMessage As String)
    End Interface


    <InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid(ClientAction.EventsId)> Public Interface IClientActionEvents
        <DispId(1)> Sub TestEvent(ByVal sender As Object, ByVal e As PacketArrivedEventArgs)
    End Interface



    <ComSourceInterfaces(GetType(IClientActionEvents)), Guid(ClientAction.ClassId), ClassInterface(ClassInterfaceType.None)> _
    Public Class ClientAction
        Implements IClientAction

        Public Delegate Sub TestEventDelegate(ByVal sender As Object, ByVal e As PacketArrivedEventArgs)

        Public Event TestEvent As TestEventDelegate

    public sub New()
        //Init etc
    end sub

    public sub SendMessage(theMessage as string) implements IClientAction.SendMessage
        onSendMessage(theMessage)
    end sub 

        Protected Sub onSendMessage(message as string)
            If mRaiseEvents Then
                RaiseEvent TestEvent(Me, New PacketArrivedEventArgs(theMessage))
            End If
        End Sub

    end Class

I've been able to get COM and .Net consumers of the Assembly/Component to work properly with events and be able to debug in and out of the component.

Hope this helps.

这篇关于在VB6代码中处理VB.NET事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆