如何:处理自动化事件 (Visual C#)

下面的过程演示了如何使用 Visual C# 外接程序处理与窗口相关的事件。

说明说明

显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您现用的设置或版本。这些过程是在“常规开发设置”处于活动状态时开发的。若要更改设置,请在“工具”菜单上选择“导入和导出设置”。有关更多信息,请参见 Visual Studio 设置

使用 Visual C# 处理与窗口相关的事件

  1. 使用 Visual C# 创建 Visual Studio 外接程序项目。

  2. OnConnection 方法中,初始化一个变量以截获事件。在以下示例中,此变量被命名为 events。

    EnvDTE.Events events = _applicationObject.Events;
    
  3. OnConnection 方法中,检索来自自动化模型的事件对象。

    winEvents = (EnvDTE.WindowEvents)events.get_WindowEvents(null);
    

    在此示例中,变量名为 winEvents。此自动化模型中的其他对象与其他类型的事件相关。例如,FindEvents 应用于与查找操作相关的事件,而 TaskListEvents 应用于与**“任务列表”**相关的事件。有关可用事件的完整列表,请参见 响应自动化事件

  4. OnConnection 方法中,连接到第三 (3) 步中使用 += 运算符检索到的事件对象所公开的每个委托。例如,若要连接 WindowClosing 事件所公开的委托,请使用:

    winEvents.WindowClosing += new  
    _dispWindowEvents_WindowClosingEventHandler(this.WindowClosing);
    
  5. 为每个与事件对象相关的事件添加过程。例如,若要处理关闭窗口时发生的事件 (WindowClosing),请使用:

    public void WindowClosing(EnvDTE.Window closingWindow)
    {
        outputWindowPane.OutputString ("WindowEvents::WindowClosing\n");
        outputWindowPane.OutputString("\tWindow: " + 
        closingWindow.Caption + "\n");
    }
    

    如果使用 WindowEvents 对象,您必须为该对象的所有事件添加过程,这些事件包括:

  6. 最后,为了防止在关闭外接程序后 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 类的代码。

请参见

任务

如何:处理自动化事件 (Visual Basic)

参考

+= 运算符(C# 参考)

其他资源

响应自动化事件

响应事件(Visual Basic 和 Visual C# 项目)