Condividi tramite


How to: Handle Events Raised by a COM Source 

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 section, see Consuming Events in the same section.

A .NET client (event sink) can receive events raised by an existing COM server (event source). COM interop generates the necessary delegates in metadata that you include in your managed client. An imported delegate signature comprises the sink event interface, an underscore, the event name, and the word EventHandler: SinkEventInterface_EventNameEventHandler.

Note that COM objects that raise events within a .NET client require two Garbage Collector (GC) collections before they are released. This is caused by the reference cycle that occurs between COM objects and managed clients. If you need to explicitly release a COM object you should call the Collect method twice.

To interoperate with an existing COM event source

  1. Obtain the primary interop assembly for the COM server if the COM types are to be shared by other applications. A primary interop assembly contains metadata representing the converted type library and is signed by the publisher.

    NoteNote

    If the primary interop assembly is not available or if the assembly is to be used privately, you can import the type library by using the Type Library Importer (Tlbimp.exe) or an equivalent API.

    The conversion process generates a delegate for each event; however, you only have to sink the events that interest you.

  2. You can use a metadata browser, such as the MSIL Disassembler (Ildasm.exe), to identify events delegates.

  3. Consume events from the COM event source the same way you consume events from a managed event source.

Example

The following example demonstrates how to open an Internet Explorer window and wire events raised by the InternetExplorer object to event handlers implemented in managed code. Definitions of Internet Explorer types (including event delegates) are imported as metadata from the SHDocVw.dll. The example sinks the TitleChange event.

Option Explicit
Option Strict

Imports System
Imports System.Runtime.InteropServices
Imports SHDocVw

Namespace InternetExplorer
    Public Class Explorer
        Public Shared Sub Main()
            Dim explorer As New Explorer()
            explorer.Run()
        End Sub
      
        Public Sub Run()
            Dim o As Object = Nothing
            Dim s As String
         
            Try
                ' Starts the browser.
                m_IExplorer = New SHDocVw.InternetExplorer()
            Catch e As Exception
                Console.WriteLine("Exception when creating Internet 
                Explorer object {0}", e)
                Return
            End Try
         
            ' Wires your event handlers to m_IExplorer.
            SetAllEvents()
         
            Try
                ' Goes to the home page.
                m_WebBrowser = CType(m_IExplorer, IWebBrowserApp)
                m_WebBrowser.Visible = True
                m_WebBrowser.GoHome()
            
                ' Starts navigating to different URLs.
                Console.Write("Enter URL (or enter to quit): ")
                s = Console.ReadLine()
                While s <> "" And Not (m_IExplorer Is Nothing) _
                And Not (m_WebBrowser Is Nothing)
                    m_WebBrowser.Navigate(s, o, o, o, o)
                    Console.Write("Enter URL (or enter to quit): ")
                    s = Console.ReadLine()
                End While
                m_WebBrowser.Quit()
            Catch sE As Exception
                If m_IExplorer Is Nothing And m_WebBrowser Is Nothing Then
                    Console.WriteLine("Internet Explorer has gone away")
                Else
                    Console.WriteLine("Exception happens {0}", sE)
                End If
            End Try
        End Sub
      
        ' Uses the AddHandler for adding delegates to events.
        Sub SetAllEvents()
            If Not (m_IExplorer Is Nothing) Then
                ' Title Change event
                ' DWebBrowserEvents2 is the name of the sink event interface.
                ' TitleChange is the name of the event.
                ' DWebBrowserEvents2_TitleChangeEventHandler is the delegate 
                ' name assigned by TlbImp.exe.
                Dim DTitleChangeE As New _
DWebBrowserEvents2_TitleChangeEventHandler(AddressOf OnTitleChange)
                AddHandler m_IExplorer.TitleChange, DTitleChangeE
            End If
        End Sub
      
        '----------------------------------------------------------------
        ' Defines event handlers.
        ' Document title changed
        Shared Sub OnTitleChange(sText As String)
            Console.WriteLine("Title changes to {0}", sText)
        End Sub
      
      
        End Sub
        '----------------------------------------------------------------
        ' The following are class fields.
        Private Shared m_IExplorer As SHDocVw.InternetExplorer = Nothing
        Private Shared m_WebBrowser As IWebBrowserApp = Nothing
    End Class
End Namespace
namespace InternetExplorer
{
    using System;
    using System.Runtime.InteropServices;
    using SHDocVw;

    public class Explorer 
    {
        public static void Main()
        {
            Explorer explorer = new Explorer();
            explorer.Run();
        }
        public void Run()
        {
            Object o = null;
            String s;

            try
            {
                // Starts the browser.
                m_IExplorer = new SHDocVw.InternetExplorer();
            }
            catch(Exception e)
            {
                Console.WriteLine("Exception when creating Internet 
                Explorer object {0}", e);
                return;
            }

            // Wires your event handlers to m_IExplorer.
            SetAllEvents();

            try
            {  
                // Goes to the home page.
                m_WebBrowser = (IWebBrowserApp) m_IExplorer;
                m_WebBrowser.Visible = true;
                m_WebBrowser.GoHome();

                // Starts navigating to different URLs.
                Console.Write("Enter URL (or enter to quit): ");
                s = Console.ReadLine();
                while (s != "" && m_IExplorer != null &&
                    m_WebBrowser != null)
                {
                    m_WebBrowser.Navigate(s, ref o, ref o, ref o,
                          ref o);
                    Console.Write("Enter URL (or enter to quit): ");      
                    s = Console.ReadLine();
                }

                m_WebBrowser.Quit();
            }
            catch(Exception sE)
            {
                if (m_IExplorer == null && m_WebBrowser == null)
                {
                    Console.WriteLine("Internet Explorer has gone away");
                }
                else
                {
                    Console.WriteLine("Exception happens {0}", sE);
                }
            }
        }
        // Uses the += syntax for adding delegates to events.
        void SetAllEvents()
        {
            if (m_IExplorer != null)
            {
                // Title Change event
                // DWebBrowserEvents2 is the name of the sink event
                //interface.
                // TitleChange is the name of the event.
                // DWebBrowserEvents2_TitleChangeEventHandler is the 
                // delegate name assigned by TlbImp.exe.
                DWebBrowserEvents2_TitleChangeEventHandler 
                   DTitleChangeE = new DWebBrowserEvents2_TitleChangeEventHandler(OnTitleChange);
                m_IExplorer.TitleChange += DTitleChangeE;
            }
        }
///////////////////////////////////////////////////////////////////////
        // Define event handlers.
        // Document title changed
        static void OnTitleChange(String Text)
        {
            Console.WriteLine("Title changes to {0}", Text);
        }
   
//////////////////////////////////////////////////////////////////////////
        // The following are class fields.
        static private SHDocVw.InternetExplorer m_IExplorer = null;
        static private IWebBrowserApp m_WebBrowser = null;
    }
}

See Also

Tasks

How to: Raise Events Handled by a COM Sink

Reference

MSIL Disassembler (Ildasm.exe)

Concepts

Exposing COM Components to the .NET Framework

Other Resources

Managed and Unmanaged Events