VSPackage にコマンドを実装するには、次のタスクを実行する必要があります。
.vsct ファイルでコマンド グループを設定し、コマンドを追加します。 詳細については、 Visual Studio コマンド テーブル (.vsct) ファイルを参照してください。
コマンドを Visual Studio に登録します。
コマンドを実装します。
以降のセクションでは、コマンドを登録して実装する方法について説明します。
Visual Studio にコマンドを登録する
コマンドをメニューに表示する場合は、VSPackage に ProvideMenuResourceAttribute を追加し、メニューの名前またはそのリソース ID の値として使用する必要があります。
[ProvideMenuResource("Menus.ctmenu", 1)]
public sealed class MyPackage : Package
{
// ...
}
さらに、コマンドを OleMenuCommandServiceに登録する必要があります。 VSPackage がGetServiceから派生している場合は、Package メソッドを使用してこのサービスを取得できます。
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 とコマンドの両方が認識される場合、メソッドは次の
prgCmdsフラグを使用して、すべてのコマンドのコマンド フラグ フィールド (OLECMDF パラメーター内) を設定する必要があります。OLECMDF_SUPPORTED: このコマンドはサポートされています。OLECMDF_INVISIBLE: コマンドは表示されません。OLECMDF_LATCHED: コマンドはオンになっており、チェックされているように見えます。OLECMDF_ENABLED: コマンドが有効になっています。OLECMDF_DEFHIDEONCTXTMENU: コマンドがショートカット メニューに表示される場合は非表示にする必要があります。OLECMDF_NINCHED: コマンドはメニュー コントローラーであり、有効になっていませんが、ドロップダウン メニュー リストは空ではなく、引き続き使用できます。 (このフラグはほとんど使用されない)。
コマンドが .vsct ファイルで
TextChangesフラグで定義されている場合は、次のパラメーターを設定します。rgwzパラメーターのpCmdText要素をコマンドの新しいテキストに設定します。cwActualパラメーターのpCmdText要素をコマンド文字列のサイズに設定します。
また、コマンドがオートメーション関数を処理することを目的としていない限り、現在のコンテキストがオートメーション関数ではないことを確認します。
特定のコマンドをサポートしていることを示すには、 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;
}