作ってみよう
Extension(RC+カスタム)では、メニュー項目の追加、プロジェクトファイルの管理、ドッキングウィンドウの表示など、Epson RC+ に独自の機能を組み込むための仕組み(拡張ポイント)を提供しています。
これらは、Extensions API が用意する拡張ポイントのためのインターフェースを、.NET の組み込み拡張フレームワークである Managed Extensibility Framework(MEF)の Export として実装することで動作します。
Extension プロジェクト作成時には、利用したい拡張ポイントを Initial Feature として選択でき、プロジェクト作成後でも新しい項目として追加することが可能です。
ここでは、拡張ポイントの実装方法の一例を示し、RC+ Extensionsプロジェクトの作成からEpson RC+での利用までの流れを説明します。
以下の手順では、Extensionのドッキングウィンドウにボタンを配置し、Extension API のインターフェースを利用してコントローラー接続/切断を行うためのサンプルを作成します。
[利用開始]の手順に従って、Extension の新しいプロジェクトを作成します。
- 名前は、ConnectControllerSample とします。
- 初期機能は、Main menu and tool bar item、および Docking window をチェックします。
- ARM64 版 Windows では、構成をx64にしてください。
Visual Studio 上でビルド、デバッグして、動作することを確認します。
- Epson RC+のメインメニュー上の拡張タブのメニュー項目に
ConnectControllerSample (xx)(xx は表示言語名)が追加され、メニュー項目を選択して、ドッキングウィンドウが表示されればOKです。

- Epson RC+のメインメニュー上の拡張タブのメニュー項目に
テンプレートの確認は完了したため、Epson RC+を終了します。
Visual Studio 上で DockingWindow フォルダーの DockingWindowContent.xaml ファイルを編集します。

- 自動生成で配置されたTextBlockの下のGrid 内に、コントローラー接続のButton、およびコントローラー切断のButtonを追加します。
- TextBlockのTextに注目してください。Captions[WindowHeader].Value にバインドしています。Extensionでは、Epson RC+の表示言語に従ってローカライズしたい文字列をCaptions.xlsxに記述します。詳細は後述しますが、Captions.xlsxのsymbol列で定義した名前(この例では WindowHeader)を使用して同様にバインドすることで、Epson RC+の表示言語に応じたローカライズが可能です。
<UserControl x:Class="ConnectControllerSample.DockingWindow.DockingWindowContent" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ConnectControllerSample.DockingWindow" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <UserControl.DataContext> <local:DockingWindowContentViewModel /> </UserControl.DataContext> <DockPanel Background="White" LastChildFill="True"> <TextBlock Margin="3,0,0,0" DockPanel.Dock="Top" FontSize="24" FontWeight="Bold" Foreground="DarkBlue" Text="{Binding Captions[WindowHeader].Value}" /> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Button x:Name="ConnectButton" Grid.Row="0" Grid.Column="0" Margin="4" HorizontalAlignment="Left" VerticalAlignment="Top" Command="{Binding ConnectCommand}" Content="Connect Controller" /> <Button x:Name="DisconnectButton" Grid.Row="0" Grid.Column="1" Margin="4" HorizontalAlignment="Left" VerticalAlignment="Top" Command="{Binding DisconnectCommand}" Content="Disconnect Controller" /> </Grid> </DockPanel> </UserControl>DockingWindowフォルダーのDockingWindowContentViewModelAddition.csを編集します。

- .xamlでコントローラー接続と切断のButtonにバインドしたConnectCommand、およびDisconnectCommandのコマンドを追加します。
- ロボットコントローラーとの接続状態は、IRCXControllerConnectionAPI(コントローラー接続API)のIsOnlineプロパティを参照することで確認できます。IsOnline は、接続が確立されている場合はtrue、切断されている場合はfalseで、それ以外(接続を確立しようとしているなどの中間状態)はnullです。
- ロボットコントローラーとの接続は、IRCXControllerConnectionAPIのConnectControllerAsyncメソッドを呼び出します。ロボットコントローラーとの切断は、コントローラー接続APIのDisconnectControllerAsyncメソッドを呼び出します。
- メッセージボックスの表示は、IRCXWindowAPI(ウィンドウAPI)のShowMessageBoxメソッドを呼び出します。
- コンストラクタで、IRCXControllerConnectionAPI、およびIRCXWindowAPIのインスタンスを、MainクラスのGetAPIメソッドを経由して、MEFのコンテナから取得します。
(前略) namespace ConnectControllerSample.DockingWindow { /// <summary> /// Extension : Docking Window (Specific Part) /// </summary> internal partial class DockingWindowContentViewModel { /// <summary> /// Connect controller command /// </summary> public AsyncReactiveCommand ConnectCommand { get; } = new AsyncReactiveCommand(); /// <summary> /// Disconnect controller command /// </summary> public AsyncReactiveCommand DisconnectCommand { get; } = new AsyncReactiveCommand(); /// <summary> /// Window-related API /// </summary> private IRCXWindowAPI _windowAPI; /// <summary> /// Controller Connection API /// </summary> private IRCXControllerConnectionAPI _connectionAPI; /// <summary> /// Constructor /// </summary> public DockingWindowContentViewModel() { _windowAPI = Main.GetAPI<IRCXWindowAPI>(); _connectionAPI = Main.GetAPI<IRCXControllerConnectionAPI>(); ConnectCommand.Subscribe(OnConnect); DisconnectCommand.Subscribe(OnDiscconect); } private async Task OnConnect() { if (_connectionAPI.IsOnline == false) { var result = await _connectionAPI.ConnectControllerAsync(); _windowAPI.ShowMessageBox( new RCXCaption(Main.CommonId, Caption.ExtensionName), new RCXCaption(result ? "Controller connection succeed." : "Controller connection failed."), IRCXWindowAPI.ButtonType.OK, IRCXWindowAPI.IconType.Information); } else { _windowAPI.ShowMessageBox( new RCXCaption(Main.CommonId, Caption.ExtensionName), new RCXCaption("The controller cannot be connected."), IRCXWindowAPI.ButtonType.OK, IRCXWindowAPI.IconType.Warning); } } private async Task OnDiscconect() { if (_connectionAPI.IsOnline == true) { await _connectionAPI.DisconnectControllerAsync(); } else { _windowAPI.ShowMessageBox( new RCXCaption(Main.CommonId, Caption.ExtensionName), new RCXCaption("The controller cannot be disconnected."), IRCXWindowAPI.ButtonType.OK, IRCXWindowAPI.IconType.Warning); } } /// <inheritdoc /> public Task WindowCreated() { return Task.CompletedTask; } } }プロジェクトフォルダー直下のCaptions.xlsxファイルを編集します。

- symbol列がWindowHeaderの行の各言語のキャプションを変更します。

リビルド、デバッグします。
- 起動したEpson RC+で、開発したExtensionのメニューまたはツールバーアイコンをクリックし、作成したDockingWindowを表示します。
- 現在のEpson RC+の言語に対応する Captions.xlsx で設定したキャプションが、画面上部に表示される事を確認します。
- [Connect Controller]ボタンと[Disconnect Controller]ボタンで、コントローラー接続と切断ができる事を確認します。

Visual Studio上でPackageItemsフォルダーのmanifest.rcxmanifestを編集します。

- Vendor Info, Extension Name, Summary, Descriptionの行の各言語の文字列を変更します。

[Extensionの配布]の手順に従って、拡張機能マネージャーに開発した Extension を表示します。
- 現在のEpson RC+の言語に対応するmanifest.rcxmanifestで設定した情報が、画面に表示される事を確認します。

- 現在のEpson RC+の言語に対応するmanifest.rcxmanifestで設定した情報が、画面に表示される事を確認します。
[Extensionの利用]の手順に従って、Extensionを有効化して開発した機能が利用できる事を確認します。