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_
メソッドは、IConnectionPointContainer
インターフェイスとIConnectionPoint
インターフェイスの両方を実装する別の IDispatch ベースのイベント オブジェクト を作成し、このオブジェクトにIDispatchpointer
を返します。オートメーションを使用してイベントを公開するには、GetAutomationObject に応答し、レジストリに追加する文字列を監視する必要があります。 基本的なプロジェクトのサンプルでは、この文字列は BscProjectsEvents と BscProjectItemsEventsです。
基本的なプロジェクトのサンプルのレジストリ エントリ
ここでは、オートメーション イベントの値を、レジストリのどこに追加するかを示します。
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Packages\<PkgGUID>\AutomationEvents]
AutomationProjectEvents = AutomationProjectEvents
オブジェクトを返します。
AutomationProjectItemEvents = AutomationProjectItemsEvents
オブジェクトを返します。
名前 | Type | Range | 説明 |
---|---|---|---|
既定値 (@) | 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
インターフェイスのイベントを検索する必要があるエンド ユーザーは、そのイベント オブジェクトの取得元がすぐにはわかりません。