방법: 자동화 이벤트 처리(Visual C#)
아래 절차에서는 Visual C# 추가 기능을 사용하여 창 관련 이벤트를 처리하는 방법을 보여 줍니다.
참고
표시되는 대화 상자와 메뉴 명령은 활성 설정이나 버전에 따라 도움말에서 설명하는 것과 다를 수 있습니다. 이러한 절차는 일반 개발 설정을 사용하여 개발되었습니다. 설정을 변경하려면 도구 메뉴에서 설정 가져오기 및 내보내기를 선택합니다. 자세한 내용은 설정에 대한 작업를 참조하십시오.
Visual C#을 사용하여 창 관련 이벤트를 처리하려면
Visual C#을 사용하여 Visual Studio 추가 기능 프로젝트를 만듭니다.
OnConnection 메서드에서 이벤트를 가로채는 변수를 초기화합니다. 아래 예제에서 이 변수의 이름은 events입니다.
EnvDTE.Events events = _applicationObject.Events;
OnConnection 메서드에서 자동화 모델의 이벤트 개체를 검색합니다.
winEvents = (EnvDTE.WindowEvents)events.get_WindowEvents(null);
이 예제에서 변수는 winEvents입니다. 자동화 모델의 다른 개체는 다른 형식의 이벤트와 연결됩니다. 예를 들어, FindEvents는 찾기 작업과 관련된 이벤트에 적용되고 TaskListEvents는 작업 목록과 관련된 이벤트에 적용됩니다. 사용할 수 있는 이벤트의 전체 목록을 보려면 자동화 이벤트에 응답을 참조하십시오.
3단계에서 검색한 이벤트 개체가 노출하는 각 대리자를 OnConnection 메서드에서 += 연산자를 사용하여 연결합니다. 예를 들어, WindowClosing 이벤트가 노출하는 대리자를 연결하려면 다음 코드를 사용합니다.
winEvents.WindowClosing += new _dispWindowEvents_WindowClosingEventHandler(this.WindowClosing);
이벤트 개체와 관련된 각 이벤트에 대한 프로시저를 추가합니다. 예를 들어, 창을 닫을 때 발생하는 이벤트(WindowClosing)를 처리하려면 다음 코드를 사용합니다.
public void WindowClosing(EnvDTE.Window closingWindow) { outputWindowPane.OutputString ("WindowEvents::WindowClosing\n"); outputWindowPane.OutputString("\tWindow: " + closingWindow.Caption + "\n"); }
WindowEvents 개체의 경우에는 다음과 같이 이 개체의 모든 이벤트에 대한 프로시저가 있어야 합니다.
마지막으로, 추가 기능을 닫은 후 Visual Studio에서 창 관련 이벤트를 계속 모니터링하여 시스템이 느려지지 않도록 이벤트 처리를 사용하지 않도록 설정합니다. Visual C#의 경우 -= 연산자를 사용합니다. 예를 들어, WindowClosing에 대한 이벤트 처리를 비활성화하려면 다음 코드를 사용합니다.
public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom) { if (winEvents != null) { winEvents.WindowClosing -= new _dispWindowEvents_WindowClosingEventHandler (this.WindowClosing); } }
이렇게 하면 추가 기능이 종료될 경우만이 아니라 추가 기능이 여전히 실행 중인 상태에서 IDE가 종료될 경우에도 이벤트 처리가 해제됩니다. IDE가 종료될 때에는 실행 중인 모든 추가 기능이 먼저 자동으로 종료됩니다.
예제
다음은 Visual C#에서 창 관련 이벤트를 가로채고 처리하는 방법을 보여 주는 기본 Visual Studio 추가 기능 예제입니다. 창 관련 이벤트가 발생할 때마다 알림 메시지가 출력 창으로 전달됩니다.
namespace CSEventsAddin
{
using System;
using Microsoft.VisualStudio.CommandBars;
using Extensibility;
using EnvDTE;
using EnvDTE80;
public class Connect : Object, IDTExtensibility2
{
public Connect()
{
}
public void OnConnection(object application, ext_ConnectMode
connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
// Retrieve the event objects from the automation model.
EnvDTE.Events events = _applicationObject.Events;
// Send event messages to the Output window.
OutputWindow outputWindow =
(OutputWindow)_applicationObject.Windows.Item
(Constants.vsWindowKindOutput).Object;
outputWindowPane = outputWindow.OutputWindowPanes.Add("DTE
Event Information");
// Retrieve the event objects from the automation model.
winEvents =
(EnvDTE.WindowEvents)events.get_WindowEvents(null);
// Connect to each delegate exposed from each object
// retrieved above.
winEvents.WindowActivated += new
_dispWindowEvents_WindowActivatedEventHandler
(this.WindowActivated);
winEvents.WindowClosing += new
_dispWindowEvents_WindowClosingEventHandler
(this.WindowClosing);
winEvents.WindowCreated += new
_dispWindowEvents_WindowCreatedEventHandler
(this.WindowCreated);
winEvents.WindowMoved += new
_dispWindowEvents_WindowMovedEventHandler
(this.WindowMoved);
}
public void OnDisconnection(ext_DisconnectMode disconnectMode,
ref Array custom)
{
// If the delegate handlers have been connected, then
// disconnect them here.
// If this is not done, the handlers may still
// fire until the next garbage collection event.
if (winEvents != null)
{
winEvents.WindowActivated -= new
_dispWindowEvents_WindowActivatedEventHandler
(this.WindowActivated);
winEvents.WindowClosing -= new
_dispWindowEvents_WindowClosingEventHandler
(this.WindowClosing);
winEvents.WindowCreated -= new
_dispWindowEvents_WindowCreatedEventHandler
(this.WindowCreated);
winEvents.WindowMoved -= new
_dispWindowEvents_WindowMovedEventHandler
(this.WindowMoved);
}
}
// Window-related events.
public void WindowClosing(EnvDTE.Window closingWindow)
{
outputWindowPane.OutputString
("WindowEvents::WindowClosing\n");
outputWindowPane.OutputString("\tWindow: " +
closingWindow.Caption + "\n");
}
public void WindowActivated(EnvDTE.Window gotFocus,
EnvDTE.Window lostFocus)
{
outputWindowPane.OutputString
("WindowEvents::WindowActivated\n");
outputWindowPane.OutputString("\tWindow receiving focus: "
+ gotFocus.Caption + "\n");
outputWindowPane.OutputString("\tWindow that lost focus: "
+ lostFocus.Caption + "\n");
}
public void WindowCreated(EnvDTE.Window window)
{
outputWindowPane.OutputString
("WindowEvents::WindowCreated\n");
outputWindowPane.OutputString("\tWindow: " + window.Caption
+ "\n");
}
public void WindowMoved(EnvDTE.Window window, int top, int
left, int width, int height)
{
outputWindowPane.OutputString
("WindowEvents::WindowMoved\n");
outputWindowPane.OutputString("\tWindow: " + window.Caption
+ "\n");
outputWindowPane.OutputString("\tLocation: (" +
top.ToString() + " , " + left.ToString() + " , " +
width.ToString() + " , " + height.ToString() + ")\n");
}
public void OnAddInsUpdate(ref Array custom)
{
}
public void OnStartupComplete(ref Array custom)
{
}
public void OnBeginShutdown(ref Array custom)
{
}
private DTE2 _applicationObject;
private AddIn _addInInstance;
private EnvDTE.WindowEvents winEvents;
private OutputWindowPane outputWindowPane;
}
}
코드 컴파일
이 코드를 컴파일하려면 새 Visual C# 추가 기능 프로젝트를 만들고 Connect 클래스의 코드를 예제의 코드로 바꿉니다.