在 Visual Studio SDK 中公开事件
Visual Studio 可让你使用自动化来获取事件源。 建议为项目和项目项获取事件源。
事件由自动化使用者从 Events 对象或 GetObject(例如 GetObject("EventObjectName")
)取回。 环境通过使用 DISPATCH_METHOD
或 DISPATCH_PROPERTYGET
标志返回事件来调用 IDispatch::Invoke
。
以下过程说明如何返回特定于 VSPackage 的事件。
环境启动。
它从注册表中读取所有 VSPackage 的 Automation、AutomationEvents 和 AutomationProperties 键下的所有值名称,并将这些名称存储在表中。
在此示例中,自动化使用者调用
DTE.Events.AutomationProjectsEvents
或DTE.Events.AutomationProjectItemsEvents
。环境会在表中查找字符串参数,并加载相应的 VSPackage。
环境通过使用在调用中传递的名称来调用 GetAutomationObject 方法;在此示例中为
AutomationProjectsEvents
或AutomationProjectItemsEvents
。VSPackage 将创建一个具有方法(如
get_AutomationProjectsEvents
或get_AutomationProjectItemEvents
)的根对象,然后返回指向该对象的 IDispatch 指针。环境根据传递到自动化调用的名称来调用相应的方法。
get_
方法创建另一个基于 IDispatch 的事件对象,该对象实现IConnectionPointContainer
接口和IConnectionPoint
接口,并将一个IDispatchpointer
返回该对象。若要使用自动化来公开事件,必须响应 GetAutomationObject 并监视你添加到注册表的字符串。 在基本项目示例中,字符串是 BscProjectsEvents 和 BscProjectItemsEvents。
来自基本项目示例的注册表项
本节显示向注册表添加自动化事件值的位置。
[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
方法。
事件的自动化模型
CProjectEventsContainer
类表示 BscProjectsEvents 的源对象,CProjectItemsEventsContainer
代表 BscProjectItemsEvents 的源对象。
在大多数情况下,必须为每个事件请求返回一个新对象,因为大多数事件对象都采用筛选器对象。 触发事件时,检查此筛选器,以验证是否正在调用事件处理程序。
AutomationEvents.h 和 AutomationEvents.cpp 包含了下表中类的声明和实现。
类 | 说明 |
---|---|
CAutomationEvents |
实现从 DTE.Events 对象取回的事件根对象。 |
CProjectsEventsContainer 和 CProjectItemsEventsContainer |
实现触发相应事件的事件源对象。 |
以下代码示例演示了如何响应事件对象请求。
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
接口的事件的最终用户来说,无法立即从中取回该事件对象的位置。