如何:引发 COM 接收器所处理的事件

如果您不熟悉 .NET Framework 提供的基于委托的事件模型,请参见处理和引发事件

.NET Framework 提供了基于委托的事件系统来将事件发送方(源)连接到事件接收方(接收器)。 当接收器是 COM 客户端时,源必须包括附加的元素,以模拟连接点。 通过这些修改,COM 客户端通过调用 IConnectionPoint::Advise 方法,可以以传统的方式来注册其事件接收接口。(Visual Basic 会隐藏连接点详细信息,因此无须直接调用这些方法。)

与 COM 事件接收器互用

  1. 在托管代码中定义事件接收接口。 此接口可以包含由托管类指明其出处的事件的子集。 接口的方法名称必须与事件名称相同。

  2. 应用 ComSourceInterfacesAttribute,将事件接收接口连接到托管类。

  3. 将包含该类的程序集导出到类型库中。 使用 Tlbexp.exe(类型库导出程序) 或等效的 API 来导出该程序集。

  4. 在 COM 中实现事件接收接口。

  5. 对于接收事件的 COM 客户端,实现由事件源在其类型库中定义的事件接收接口。 然后,使用连接点机制将接收接口连接到事件源。

示例

下面的示例将托管服务器显示为事件源,将 COM 客户端显示为事件接收器。 托管服务器将 ButtonEvents 声明为事件接收接口,并将该接口连接到 Button 类。 非托管客户端将创建 Button 类的一个实例并实现事件接收接口。

' Managed server (event source)
Option Explicit
Option Strict

Imports System
Imports System.Runtime.InteropServices

Namespace EventSource
    Public Delegate Sub ClickDelegate(x As Integer, y As Integer)
    Public Delegate Sub ResizeDelegate()
    Public Delegate Sub PulseDelegate()
   
    ' Step 1: Defines an event sink interface (ButtonEvents) to be
    ' implemented by the COM sink.
    <GuidAttribute("1A585C4D-3371-48dc-AF8A-AFFECC1B0967"), _
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)> _
    Public Interface ButtonEvents
        Sub Click(x As Integer, y As Integer)
        Sub Resize()
        Sub Pulse()
    End Interface
   
    ' Step 2: Connects the event sink interface to a class 
    ' by passing the namespace and event sink interface
    ' ("EventSource.ButtonEvents, EventSrc").
    <ComSourceInterfaces(GetType(ButtonEvents))> _
    Public Class Button
        Public Event Click As ClickDelegate
        Public Event Resize As ResizeDelegate
        Public Event Pulse As PulseDelegate
      
      
        Public Sub CauseClickEvent(x As Integer, y As Integer)
            RaiseEvent Click(x, y)
        End Sub
      
        Public Sub CauseResizeEvent()
            RaiseEvent Resize()
        End Sub
      
        Public Sub CausePulse()
            RaiseEvent Pulse()
        End Sub
    End Class
End Namespace
using System;
using System.Runtime.InteropServices;
namespace EventSource
{
    public delegate void ClickDelegate(int x, int y);
    public delegate void ResizeDelegate();
    public delegate void PulseDelegate();
   
    // Step 1: Defines an event sink interface (ButtonEvents) to be     
    // implemented by the COM sink.
    [GuidAttribute("1A585C4D-3371-48dc-AF8A-AFFECC1B0967") ]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
    public interface ButtonEvents
    {
        void Click(int x, int y);
        void Resize();
        void Pulse();
    }
    // Step 2: Connects the event sink interface to a class 
    // by passing the namespace and event sink interface
    // ("EventSource.ButtonEvents, EventSrc").
    [ComSourceInterfaces(typeof(ButtonEvents))]
    public class Button
    {
        public event ClickDelegate Click;
        public event ResizeDelegate Resize;
        public event PulseDelegate Pulse;
      
        public Button()
        {
        }
        public void CauseClickEvent(int x, int y)
        { 
            Click(x, y);
        }
        public void CauseResizeEvent()
        { 
            Resize();
        }
        public void CausePulse()
        {
            Pulse();
        }
    }
}
' COM client (event sink)
' This Visual Basic 6.0 client creates an instance of the Button class and 
' implements the event sink interface. The WithEvents directive 
' registers the sink interface pointer with the source.
Public WithEvents myButton As Button

Private Sub Class_Initialize()
    Dim o As Object
    Set o = New Button
    Set myButton = o
End Sub
' Events and methods are matched by name and signature.
Private Sub myButton_Click(ByVal x As Long, ByVal y As Long)
    MsgBox "Click event"
End Sub

Private Sub myButton_Resize()
    MsgBox "Resize event"
End Sub

Private Sub myButton_Pulse()
End Sub

请参见

任务

如何:处理 COM 源引发的事件

参考

ComSourceInterfacesAttribute

概念

向 COM 公开 .NET Framework 组件

其他资源

托管和非托管事件