Udostępnij za pośrednictwem


How to: Raise Events Handled by a COM Sink

If you are not familiar with the delegate-based event model provided by the .NET Framework, see Handling and Raising Events. For specific details that apply to this topic, see Raising an Event in the same section.

The .NET Framework provides a delegate-based event system to connect an event sender (source) to an event receiver (sink). When the sink is a COM client, the source must include additional elements to simulate connection points. With these modifications, a COM client can register its event sink interface in the traditional way by calling the IConnectionPoint::Advise method. (Visual Basic hides connection point details, so you do not have to call these methods directly.)

To interoperate with a COM event sink

  1. Define the event sink interface in managed code. This interface may contain a subset of the events sourced by a managed class. The method names of the interface must be the same as the event names.

  2. Apply the ComSourceInterfacesAttribute to connect the event sink interface to the managed class.

  3. Export the assembly containing the class to a type library. Use the Type Library Exporter (Tlbexp.exe) or an equivalent API to export the assembly.

  4. Implement the event sink interface in COM.

  5. For COM clients that sink events, implement the event sink interface defined by the event source in its type library. Then use the connection point mechanism to connect the sink interface to the event source.

Example

The following example shows a managed server as the event source and a COM client as the event sink. The managed server declares ButtonEvents as an event sink interface and connects the interface to the Button class. The unmanaged client creates an instance of the Button class and implements the event sink interface.

' 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

See Also

Tasks

How to: Handle Events Raised by a COM Source

Concepts

Exposing .NET Framework Components to COM

Reference

ComSourceInterfacesAttribute

Other Resources

Managed and Unmanaged Events