Практическое руководство. Обработка событий, вызванных COM-источником
Обновлен: Ноябрь 2007
Чтобы познакомиться с моделью событий на основе делегатов, предоставляемой средой .NET Framework, можно обратиться к разделу Обработка и создание событий. Конкретные подробности, применяемые к этому разделу, см. в подразделе Применение событий данного раздела.
Клиент .NET (приемник событий) может получать события, вызванные существующим COM-сервером (источником событий). COM-взаимодействие создает необходимые делегаты в метаданных, включаемых разработчиком в управляемый клиент. Импортируемая подпись делегата состоит из имени интерфейса события приемника, знака подчеркивания, имени события и слова EventHandler: ИнтерфейсСобытияПриемника_ИмяСобытияEventHandler.
Обратите внимание, что COM-объектам, вызывающим события внутри клиента .NET, требуются две коллекции сборщика перед их освобождением. Причиной этого является цикл ссылочный цикл, возникающий между COM-объектами и управляемыми клиентами. Если нужно явно освободить COM-объект, следует вызвать метод Collect дважды.
Взаимодействие с существующим источником событий COM
Если COM-типы предполагается использовать совместно с другими приложениями, нужно получить основную сборку взаимодействия для COM-сервера,. Основная сборка взаимодействия содержит метаданные, представляющие собой преобразованную библиотеку типов, и подписана издателем.
Примечание. Если основная сборка взаимодействия недоступна или предназначается для закрытого использования, можно импортировать библиотеку типов с помощью программы импорта библиотеки типов (Tlbimp.exe) или эквивалентного интерфейса API.
В процессе преобразования создается делегат для каждого события; однако необходимо обеспечить прием только нужных разработчику событий.
Можно использовать обозреватель метаданных, например дизассемблер MSIL Disassembler (Ildasm.exe), чтобы определить делегаты событий.
События из источника событий COM можно получать точно так же, как и из управляемого источника событий.
Пример
В следующем примере показывается, как открывать окно обозревателя Internet Explorer и связывать события, вызываемые объектом InternetExplorer, с обработчиками событий, реализованными в управляемом коде. Определения типов Internet Explorer (включая делегаты событий) импортируются в виде метаданных из SHDocVw.dll. В этом примере принимается событие TitleChange.
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;
}
}
См. также
Задачи
Практическое руководство. Вызов событий, обрабатываемых приемником COM
Основные понятия
Предоставление клиентам .NET Framework доступа к COM-компонентам
Ссылки
Дизассемблер MSIL (Ildasm.exe)