在 Visual Studio SDK 中公开事件

Visual Studio 可让你使用自动化来获取事件源。 建议为项目和项目项获取事件源。

事件由自动化使用者从 Events 对象或 GetObject(例如 GetObject("EventObjectName"))取回。 环境通过使用 DISPATCH_METHODDISPATCH_PROPERTYGET 标志返回事件来调用 IDispatch::Invoke

以下过程说明如何返回特定于 VSPackage 的事件。

  1. 环境启动。

  2. 它从注册表中读取所有 VSPackage 的 AutomationAutomationEventsAutomationProperties 键下的所有值名称,并将这些名称存储在表中。

  3. 在此示例中,自动化使用者调用 DTE.Events.AutomationProjectsEventsDTE.Events.AutomationProjectItemsEvents

  4. 环境会在表中查找字符串参数,并加载相应的 VSPackage。

  5. 环境通过使用在调用中传递的名称来调用 GetAutomationObject 方法;在此示例中为 AutomationProjectsEventsAutomationProjectItemsEvents

  6. VSPackage 将创建一个具有方法(如 get_AutomationProjectsEventsget_AutomationProjectItemEvents)的根对象,然后返回指向该对象的 IDispatch 指针。

  7. 环境根据传递到自动化调用的名称来调用相应的方法。

  8. get_ 方法创建另一个基于 IDispatch 的事件对象,该对象实现 IConnectionPointContainer 接口和 IConnectionPoint 接口,并将一个 IDispatchpointer 返回该对象。

    若要使用自动化来公开事件,必须响应 GetAutomationObject 并监视你添加到注册表的字符串。 在基本项目示例中,字符串是 BscProjectsEventsBscProjectItemsEvents

来自基本项目示例的注册表项

本节显示向注册表添加自动化事件值的位置。

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Packages\<PkgGUID>\AutomationEvents]

AutomationProjectEvents = 返回 AutomationProjectEvents 对象。

AutomationProjectItemEvents = 返回 AutomationProjectItemsEvents 对象。

名称 类型 范围 说明
默认值 (@) REG_SZ 未使用 未使用。 可将数据字段用于文档。
AutomationProjectsEvents REG_SZ 事件对象的名称。 只有密钥名称是相关的。 可将数据字段用于文档。

此示例来自基本项目示例。
AutomationProjectItemEvents REG_SZ 事件对象的名称 只有密钥名称是相关的。 可将数据字段用于文档。

此示例来自基本项目示例。

当自动化使用者请求任何事件对象时,创建一个根对象,其中包含 VSPackage 支持的任何事件的方法。 环境对此对象调用适当的 get_ 方法。 例如,如果调用 DTE.Events.AutomationProjectsEvents,则会调用根对象上的 get_AutomationProjectsEvents 方法。

Visual Studio 项目事件

事件的自动化模型

CProjectEventsContainer 类表示 BscProjectsEvents 的源对象,CProjectItemsEventsContainer 代表 BscProjectItemsEvents 的源对象。

在大多数情况下,必须为每个事件请求返回一个新对象,因为大多数事件对象都采用筛选器对象。 触发事件时,检查此筛选器,以验证是否正在调用事件处理程序。

AutomationEvents.hAutomationEvents.cpp 包含了下表中类的声明和实现。

说明
CAutomationEvents 实现从 DTE.Events 对象取回的事件根对象。
CProjectsEventsContainerCProjectItemsEventsContainer 实现触发相应事件的事件源对象。

以下代码示例演示了如何响应事件对象请求。

STDMETHODIMP CVsPackage::GetAutomationObject(
    /* [in]  */ LPCOLESTR       pszPropName,
    /* [out] */ IDispatch **    ppIDispatch)
{
    ExpectedPtrRet(ppIDispatch);
    *ppIDispatch = NULL;

    if (_wcsicmp(pszPropName, g_wszAutomationProjects) == 0)
        //Is the requested name our Projects object?
    {
        return GetAutomationProjects(ppIDispatch);
        // Gets our Projects object.
    }
    else if (_wcsicmp(pszPropName, g_wszAutomationProjectsEvents) == 0)
        //Is the requested name our ProjectsEvents object?
    {
        return CAutomationEvents::GetAutomationEvents(ppIDispatch);
          // Gets our ProjectEvents object.
    }
    else if (_wcsicmp(pszPropName, g_wszAutomationProjectItemsEvents) == 0)  //Is the requested name our ProjectsItemsEvents object?
    {
        return CAutomationEvents::GetAutomationEvents(ppIDispatch);
          // Gets our ProjectItemsEvents object.
    }
    return E_INVALIDARG;
}

在上面的代码中,g_wszAutomationProjects 是项目集合 (FigProjects) 的名称,g_wszAutomationProjectsEvents (FigProjectsEvents) 和 g_wszAutomationProjectItemsEvents (FigProjectItemEvents) 是源自 VSPackage 实现的项目事件和项目项事件的名称。

从同一中心位置取回事件对象(DTE.Events 对象)。 这样,所有事件对象都组合在一起,以便最终用户不必浏览整个对象模型即可查找特定事件。 这还让你能提供特定的 VSPackage 对象,而无需为系统范围事件实现自己的代码。 但是,对于必须查找 ProjectItem 接口的事件的最终用户来说,无法立即从中取回该事件对象的位置。