如何:引发 COM 接收器所处理的事件
更新:2007 年 11 月
如果您不熟悉 .NET Framework 提供的基于委托的事件模型,请参见处理和引发事件。有关适用于本主题的特定详细信息,请参见同一节中的 引发事件。
.NET Framework 提供了基于委托的事件系统来将事件发送方(源)连接到事件接收方(接收器)。当接收器是 COM 客户端时,源必须包括附加的元素,以模拟连接点。通过这些修改,COM 客户端通过调用 IConnectionPoint::Advise 方法,可以以传统的方式来注册其事件接收接口。(Visual Basic 会隐藏连接点详细信息,因此无须直接调用这些方法。)
与 COM 事件接收器互用
在托管代码中定义事件接收接口。此接口可以包含由托管类指明其出处的事件的子集。接口的方法名称必须与事件名称相同。
应用 ComSourceInterfacesAttribute,将事件接收接口连接到托管类。
将包含该类的程序集导出到类型库中。使用 类型库导出程序 (Tlbexp.exe) 或等效的 API 来导出该程序集。
在 COM 中实现事件接收接口。
对于接收事件的 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