コマンド

コマンド

Revit API では既存の Revit コマンドにアクセスすることができます。コマンドはタブ、アプリケーション メニュー、右クリック メニューのいずれかに配置されています。API を使用して Revit コマンドを操作する主な方法は、既存のコマンドの実装を置き換えるか、コマンドをポストすることです。

Revit コマンドを変更する

AddInCommandBinding クラスを使用すると、Revit の既存のコマンドを変更できます。既存のコマンドの実装の置換には、3 つの関連イベントがあります。

  • BeforeExecuted - この読み込み専用イベントは関連するコマンドが実行される前に発生します。アプリケーションはこのイベントに応答できますが、ドキュメントに変更を加えたり、コマンドの呼び出しに影響を与えることはありません。
  • CanExecute - 関連するコマンドが、コマンドをコマンド ターゲットで実行できるかどうかの確認を開始したときに発生するイベントです。
  • Executed - 関連するコマンドが実行されたときに、実装の変更を行う必要がある場所でこのイベントが発生します。

コマンドのバインドを作成するには、UIApplication.CreateAddInCommandBinding()か UIC ntrolledApplication.CreateAddInCommandBinding()のいずれかを呼び出します。両方のメソッドとも、置き換えるコマンド ハンドラを特定するには、RevitCommandId ID が必要になります。RevitCommandId にはコマンドの ID を取得するための静的メソッドが 2 つあります。

  • LookupCommandId - 特定の ID 文字列を使用して Revit コマンド ID を取得します。コマンド ID 文字列を検索するには、Revit のセッションを開き、目的のコマンドを呼び出し、Revit を終了して、該当のセッションからジャーナルを確認します。選択時に記録される「Jrn.Command」エントリには LookupCommandId()に必要な文字列が含まれており、その文字列は「ID_EDIT_DESIGNOPTIONS」のようになります。
  • LookupPostableCommandId - PostableCommand 列挙を使用して Revit コマンド ID を取得します。これはポスト可能なコマンド(次のセクションで説明)にのみ機能します。

Revit 2014 SDK の DisableCommand サンプルにある次の例では、AddInCommandBinding を作成して実装を変更し、ユーザにメッセージを表示してコマンドを無効にする方法を説明します。

コード領域: コマンドを変更

/// <summary>
/// Implements the Revit add-in interface IExternalApplication
/// </summary>
public class Application : IExternalApplication
{
    #region IExternalApplication Members
      
    /// <summary>
    /// Implements the OnStartup event
    /// </summary>
    /// <param name="application"></param>
    /// <returns></returns>
    public Result OnStartup(UIControlledApplication application)
    {
        // Lookup the desired command by name
        s_commandId = RevitCommandId.LookupCommandId(s_commandToDisable);

        // Confirm that the command can be overridden
        if (!s_commandId.CanHaveBinding)
        {
            ShowDialog("Error", "The target command " + s_commandToDisable +
                        " selected for disabling cannot be overridden");
   return Result.Failed;
        }

        // Create a binding to override the command.
        // Note that you could also implement .CanExecute to override the accessibiliy of the command.
        // Doing so would allow the command to be grayed out permanently or selectively, however,
        // no feedback would be available to the user about why the command is grayed out.
        try
        {
            AddInCommandBinding commandBinding = application.CreateAddInCommandBinding(s_commandId);
            commandBinding.Executed += DisableEvent;
        }
        // Most likely, this is because someone else has bound this command already.
        catch (Exception)
        {
            ShowDialog("Error", "This add-in is unable to disable the target command " + s_commandToDisable +
                        "; most likely another add-in has overridden this command.");
        }

        return Result.Succeeded;
    }

    /// <summary>
    /// Implements the OnShutdown event
    /// </summary>
    /// <param name="application"></param>
    /// <returns></returns>
    public Result OnShutdown(UIControlledApplication application)
    {
        // Remove the command binding on shutdown
        if (s_commandId.HasBinding)
            application.RemoveAddInCommandBinding(s_commandId);
        return Result.Succeeded;
    }

    #endregion

    /// <summary>
    /// A command execution method which disables any command it is applied to (with a user-visible message).
    /// </summary>
    /// <param name="sender">Event sender.</param>
    /// <param name="args">Arguments.</param>
    private void DisableEvent(object sender, ExecutedEventArgs args)
    {
        ShowDialog("Disabled", "Use of this command has been disabled.");
    }

    /// <summary>
    /// Show a task dialog with a message and title.
    /// </summary>
    /// <param name="title">The title.</param>
    /// <param name="message">The message.</param>
    private static void ShowDialog(string title, string message)
    {
        // Show the user a message.
        TaskDialog td = new TaskDialog(title)
        {
            MainInstruction = message,
            TitleAutoPrefix = false
        };
        td.Show();
    }

    /// <summary>
    /// The string name of the command to disable.  To lookup a command id string, open a session of Revit,
    /// invoke the desired command, close Revit, then look to the journal from that session.  The command
    /// id string will be toward the end of the journal, look for the "Jrn.Command" entry that was recorded
    /// when it was selected.
    /// </summary>
    static String s_commandToDisable = "ID_EDIT_DESIGNOPTIONS";

    /// <summary>
    /// The command id, stored statically to allow for removal of the command binding.
    /// </summary>
    static RevitCommandId s_commandId;

}

コマンドをポストする

UIApplication.PostCommand()メソッドは、現在の API アプリケーションからコントロールが返されたときにコマンドを呼び出せるように、Revit メッセージ キューにコマンドをポストします。この方法でポストできるのは特定のコマンドのみです。Autodesk.Revit.UI.PostableCommand 列挙型のすべてのコマンドやアドインによって作成される外部コマンドなどがそのコマンドになります。

注: ポスト可能なコマンドでも PostCommand()使用時に実行できない場合があります。たとえば、別のコマンドが既にポストされていると実行できないことがあります。Revit に一度にポストできるコマンドは 1 つに限定される場合があり、そのようなときに 2 番目のコマンドがポストされると、PostCommand()により例外が発生します。ポストされたコマンドが実行されないその他の理由としては、実行されるコマンドにアクセスできない場合があります。アクセス可能かどうかは、Revit が API コンテキストから戻ったときにのみ判断されるため、これが原因となって発生した実行エラーは、コマンドをポストしたアプリケーションに直接報告されません。

UIApplication.CanPostCommand()を使用すると、特定のコマンドがポスト可能かどうか、つまり PostableCommand か外部コマンドかを判断できます。コマンドが現在アクセス可能かどうかは判断しません。

PostCommand()と CanPostCommand()はともに RevitCommandId を必要とします。これは上記の「Revit コマンドを変更する」に記載の手順で取得できます。