次の方法で共有


コマンドの実装

VSPackage にコマンドを実装するには、次のタスクを実行する必要があります。

  1. .vsct ファイルでコマンド グループを設定し、コマンドを追加します。 詳細については、 Visual Studio コマンド テーブル (.vsct) ファイルを参照してください。

  2. コマンドを Visual Studio に登録します。

  3. コマンドを実装します。

以降のセクションでは、コマンドを登録して実装する方法について説明します。

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;
}