Condividi tramite


Procedura: generare eventi gestiti da un sink COM

Se non si ha familiarità con il modello eventi basato sui delegati fornito da .NET Framework, vedere Gestione e generazione di eventi. Per informazioni dettagliate sugli argomenti riportati di seguito, vedere Generazione di un evento più avanti in questa sezione.

.NET Framework fornisce un sistema di gestione degli eventi che utilizza i delegati per connettere il mittente dell'evento (origine) al ricevente (sink). Quando il sink è un client COM, l'origine deve includere elementi aggiuntivi che simulino i punti di connessione. Grazie a questo accorgimento, un client COM può registrare l'interfaccia del proprio sink di evento nel modo tradizionale chiamando il metodo IConnectionPoint::Advise. Poiché Visual Basic nasconde i dettagli dei punti di connessione, non occorre chiamare tali metodi direttamente.

Per interoperare con un sink di evento COM

  1. Definire l'interfaccia del sink di evento nel codice gestito. Tale interfaccia può contenere un sottoinsieme degli eventi originati da una classe gestita. I nomi dei metodi dell'interfaccia devono corrispondere ai nomi degli eventi.

  2. Utilizzare ComSourceInterfacesAttribute per connettere l'interfaccia del sink di evento alla classe gestita.

  3. Esportare l'assembly contenente la classe in una libreria dei tipi. Eseguire l'esportazione utilizzando Tlbexp.exe (utilità di esportazione della libreria dei tipi) o un'API equivalente.

  4. Implementare l'interfaccia del sink di evento in COM.

  5. Per i client COM che effettuano il sink di eventi, implementare l'interfaccia del sink di evento definita dall'origine evento nella relativa libreria dei tipi. Utilizzare quindi il meccanismo dei punti di connessione per connettere l'interfaccia del sink all'origine evento.

Esempio

Nell'esempio riportato di seguito viene illustrato un server gestito come origine eventi e un client COM come sink di evento. Il server gestito dichiara ButtonEvents come interfaccia del sink di evento e connette l'interfaccia alla classe Button. Il client non gestito crea un'istanza della classe Button e implementa l'interfaccia del sink di evento.

' 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

Vedere anche

Attività

Procedura: gestire gli eventi generati da un'origine COM

Riferimenti

ComSourceInterfacesAttribute

Concetti

Esposizione di componenti .NET Framework a COM

Altre risorse

Eventi gestiti e non gestiti