방법: COM 소스에서 발생하는 이벤트 처리
.NET Framework에서 제공하는 대리자 기반 이벤트 모델 개념을 잘 모르면 이벤트 처리 및 발생을 참조하십시오. 이 단원에 적용되는 특정한 내용을 보려면 같은 단원의 이벤트 사용을 참조하십시오.
.NET 클라이언트(이벤트 싱크)는 기존의 COM 서버(이벤트 소스)에서 발생한 이벤트를 받습니다. COM interop는 관리되는 클라이언트에 포함한 메타데이터에서 필요한 대리자를 생성합니다. 가져온 대리자 시그니처는 싱크 이벤트 인터페이스, 밑줄, 이벤트 이름 및 단어 EventHandler로 구성됩니다(예: SinkEventInterface_EventNameEventHandler).
.NET 클라이언트 내에서 이벤트를 발생시키는 COM 개체는 가비지 수집기(GC) 컬렉션 두 개가 있어야 해제할 수 있습니다. 이것은 COM 개체와 관리되는 클라이언트 사이에 발생하는 참조 주기 때문입니다. COM 개체를 명시적으로 해제하려면 Collect 메서드를 두 번 호출해야 합니다.
기존의 COM 이벤트 소스와 상호 운용하려면
다른 응용 프로그램에서 COM 형식을 공유하는 경우 COM 서버에 대한 주 interop 어셈블리를 얻습니다. 주 interop 어셈블리는 변환된 형식 라이브러리를 나타내는 메타데이터를 포함하고 게시자가 서명합니다.
참고 주 interop 어셈블리를 사용할 수 없거나 어셈블리가 전용으로 사용되는 경우에는 형식 라이브러리 가져오기(Tlbimp.exe) 또는 이와 동등한 API를 사용하여 형식 라이브러리를 가져올 수 있습니다.
변환 프로세스를 통해 각 이벤트에 대한 대리자가 생성되지만 필요한 이벤트만 싱크해야 합니다.
MSIL 디스어셈블러(Ildasm.exe)와 같은 메타데이터 브라우저를 사용하여 이벤트 대리자를 식별할 수 있습니다.
관리되는 이벤트 소스에서 이벤트를 사용하는 것과 같은 방식으로 COM 이벤트 소스에서 이벤트를 사용합니다.
예제
다음 예제에서는 Internet Explorer 창을 열고 InternetExplorer 개체에 의해 발생된 이벤트와 관리 코드에서 구현된 이벤트 처리기를 연결하는 방법을 보여 줍니다. SHDocVw.dll에서 Internet Explorer 형식 정의(이벤트 대리자 포함)를 메타데이터로 가져옵니다. 예제에서는 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;
}
}