コマンドの実装
VSPackage でコマンドを実装するには、次のタスクを実行する必要があります。
.vsct ファイルで、コマンド グループを設定し、コマンドを追加します。 詳細については、「Visual Studio コマンド テーブル (.vsct) ファイル」を参照してください。
コマンドを Visual Studio に登録します。
コマンドを実装します。
次のセクションでは、コマンドを登録して実装する方法について説明します。
コマンドを Visual Studio に登録する
メニューにコマンドが表示されるようにするには、ProvideMenuResourceAttribute を VSPackage に追加し、メニューの名前またはそのリソース ID のいずれかを値として使用する必要があります。
[ProvideMenuResource("Menus.ctmenu", 1)]
public sealed class MyPackage : Package
{
// ...
}
また、コマンドを OleMenuCommandService に登録する必要があります。 VSPackage が Package から派生している場合は、GetService メソッドを使用してこのサービスを取得できます。
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (mcs is not null)
{
// Create the command for the menu item.
CommandID menuCommandID = new CommandID(guidCommandGroup, myCommandID);
MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
mcs.AddCommand(menuItem);
}
コマンドを実装する
コマンドを実装するにはいくつかの方法があります。 常に同じように表示されるコマンドである静的メニュー コマンドが必要な場合は、前のセクションの例に示すように、MenuCommand を使用してコマンドを作成します。 静的コマンドを作成するには、コマンドを実行するイベント ハンドラーを指定する必要があります。 コマンドは常に有効で表示されているため、Visual Studio にその状態を指定する必要はありません。 特定の条件に応じてコマンドの状態を変更する場合は、OleMenuCommand クラスのインスタンスとしてコマンドを作成し、そのコンストラクターで、コマンドを実行するためのイベント ハンドラーと、コマンドの状態が変化したときに Visual Studio に通知する QueryStatus
ハンドラーを指定します。 IOleCommandTarget をコマンド クラスの一部として実装することも、プロジェクトの一部としてコマンドを指定する場合は IVsHierarchy を実装することもできます。 2 つのインターフェイスと OleMenuCommand クラスにはすべて、コマンドの状態の変更を Visual Studio に通知するメソッドと、コマンドを実行するその他のメソッドがあります。
コマンドは、コマンド サービスに追加されると、コマンドのチェーンの 1 つになります。 コマンドの状態通知と実行メソッドを実装する場合は、その特定のコマンドについてだけ指定し、その他のすべてのケースをチェーン内の他のコマンドに渡すように注意してください。 (通常は OLECMDERR_E_NOTSUPPORTED を返すことで) コマンドを渡すことができない場合、Visual Studio は正常に動作しなくなる可能性があります。
QueryStatus メソッド
QueryStatus メソッドまたは QueryStatusCommand メソッドのいずれかを実装する場合は、コマンドが属するコマンド セットの GUID とコマンドの ID を確認します。 以下のガイドラインに従います。
GUID が認識されない場合、いずれかのメソッドの実装では OLECMDERR_E_UNKNOWNGROUP を返す必要があります。
いずれかのメソッドの実装で GUID が認識されていても、コマンドが実装されていない場合、メソッドでは OLECMDERR_E_NOTSUPPORTED を返す必要があります。
いずれのメソッドの実装でも GUID とコマンドの両方が認識されている場合、メソッドでは、次の OLECMDF フラグを使用して、(
prgCmds
パラメーター内の) すべてのコマンドのコマンド フラグ フィールドを設定する必要があります。OLECMDF_SUPPORTED
: コマンドはサポートされます。OLECMDF_INVISIBLE
: コマンドを参照可能にすることはできません。OLECMDF_LATCHED
: コマンドはオンに切り替えられ、チェック済みのように表示されます。OLECMDF_ENABLED
: コマンドは有効です。OLECMDF_DEFHIDEONCTXTMENU
: ショートカット メニューに表示されている場合は、コマンドを非表示にする必要があります。OLECMDF_NINCHED
: コマンドはメニュー コントローラーであり、有効になっていませんが、ドロップダウン メニュー リストが空ではなく、引き続き使用できます。 (このフラグはほとんど使用されません)。
TextChanges
フラグを使用してコマンドが .vsct ファイルで定義されている場合は、次のパラメーターを設定します。pCmdText
パラメーターのrgwz
要素をコマンドの新しいテキストに設定します。pCmdText
パラメーターのcwActual
要素をコマンド文字列のサイズに設定します。
また、コマンドの目的が特にオートメーション関数を処理することである場合を除き、現在のコンテキストがオートメーション関数でないことを確認してください。
特定のコマンドをサポートしていることを示すには、S_OK を返します。 それ以外のすべてのコマンドについては、OLECMDERR_E_NOTSUPPORTED を返します。
次の例の QueryStatus
メソッドでは、最初にコンテキストがオートメーション関数でないことを確認し、次に正しいコマンド セット GUID とコマンド ID を検索します。 コマンド自体は有効に設定され、サポートされます。 その他のコマンドがサポートされません。
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
{
if (!VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
{
if (pguidCmdGroup == VSConstants.VSStd2K && cCmds > 0)
{
// make the Right command visible
if ((uint)prgCmds[0].cmdID == (uint)VSConstants.VSStd2KCmdID.RIGHT)
{
prgCmds[0].cmdf = (int)Microsoft.VisualStudio.OLE.Interop.Constants.MSOCMDF_ENABLED | (int)Microsoft.VisualStudio.OLE.Interop.Constants.MSOCMDF_SUPPORTED;
return VSConstants.S_OK;
}
}
}
return Constants.OLECMDERR_E_NOTSUPPORTED;
}
実行メソッド
Exec
メソッドの実装は、QueryStatus
メソッドの実装に似ています。 まず、コンテキストがオートメーション関数ではないことを確認します。 次に、GUID とコマンド ID の両方をテストします。 GUID またはコマンド ID が認識されない場合は、OLECMDERR_E_NOTSUPPORTED を返します。
コマンドを処理するには、これを実行して、実行が成功した場合は S_OK を返します。 コマンドでは、エラーの検出と通知を行います。そのため、実行が失敗した場合は、エラー コードを返します。 次の例は、実行メソッドを実装する方法を示しています。
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
{
if (!VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
{
if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
{
if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RIGHT)
{
// execute the command
return VSConstants.S_OK;
}
}
}
return Constants.OLECMDERR_E_NOTSUPPORTED;
}