デバイス設定ダイアログの作成

デバイス設定のダイアログをカスタマイズする方法について説明します。コードは再利用可能な形で提供されるため、自分で作成したアプリケーションにも簡単に組み込むことが可能です。
IC Imaging Control はデバイスの選択、セットアップが可能な既成のダイアログクラスライブラリリファレンスクラス>ICImagingControl>ICImagingControl.ShowDeviceSettingsDialog Methodを提供していますが、もしそれがお使いの用途に合わない場合は、こちらのカスタムダイアログを参考にして独自のダイアログを作成することができます。まず最初にサンプルのコードをどのようにあなたのプロジェクトに組み込むか、それからダイアログの作成する方法について解説します。


サンプルコードをロジェクトに組み込む

今回のサンプルプログラムのC#用のソースコードはMyDocuments/IC Imaging Control 3.5内の以下のディレクトリ に格納されています。
samples\C# *\Making Device Settings

サンプルコードをプロジェクトに組み込むには、frmDeviceSettings.csを追加するだけです。メ ニューよりプロジェクトを選択し、 次に既存項目の追加を選択します。sampleフォルダまで進みfrmDeviceSettings.csを開きます。
お使いのアプリケーションからダイアログを呼び出すには、最初にダイアログのインスタンスが必要となります。インスタンスの作成後、ICImagingControlクラスライブラリリファレンスクラス>ICImagingControl変数(icImagingControl1 にあります) をダイアログに割り当て、表示します。終了後はDisposeをコールしてください。

[C#]
using( frmDeviceSettings DeviceDialog = new frmDeviceSettings( icImagingControl1 ) )
{
    DeviceDialog.ShowDialog();
}

ダイアログの作成

このチャプターではデバイス設定ダイアログに焦点をあてます。もちろんそれに加えて呼び出すためのアプリケーションも必要となります。ここで紹介するサンプルコードはダイアログを呼び出すための簡単なアプリケーション付きプロジェクトを含んでおり、すぐに実行可能となっています。
すでにメインプロジェクトは作成されているかと思いますので、今回は新しいフォームをプロジェクトに追加します。このフォームはカスタムダイ アログの要素を持つものになります。新しいフォームを追加するために、メニューよりプロジェクトWindows フォームの追加と選択しDialog タイプを選択して、名前をfrmDeviceSettingsと付けて追加 ボタンをクリックします。
フォームにコンボボックスを5つ追加します。それぞれ名前をcboDevice,cboVideoNorm, cboVideoFormat,cboFrameRate,cboInputChannelと付けます。さらにtxtSerialというテキストボックスとchkFlipVchkFlipHと名前を付けたチェックボックス2つを加えます。
上記のようなコントロールに加えて、サンプルのダイアログは lblErrorMessage.という名前のラベルを持っています。このラベルのVisibleプロパティはfalseに 設定して、ダイアログに表示されないようにします。この理由に関ついてForm_Loadイベントについて説明する際にします。


ダイアログに機能を追加する

最初にいくつかグローバル変数を追加します。

[C#]
private TIS.Imaging.ICImagingControl imagingControl;
private string deviceState;
private const string not_available_text = "n/a";

ImagingControlはダイアログがコールされる前にメインプログラムからアサインされますので、publicである必要があります。ではForm_Load イベントを追加し、以下のコードを挿入してください。

[C#]
private void frmDeviceSettings_Load( object sender, EventArgs e )
{
     if ( ImagingControl.DeviceValid )
     {
         if ( ImagingControl.LiveVideoRunning )
         {
             lblErrorMessage.Text =
               "デバイス設定ダイアログはLiveVideo中は使用できません。\n \nLiveVideoを停止してください。";
             lblErrorMessage.AutoSize = false;
             lblErrorMessage.Padding = new Padding( 8 );
             lblErrorMessage.SetBounds( 0, 0, 100, cmdOK.Top );
             lblErrorMessage.Dock = DockStyle.Top;
             lblErrorMessage.Visible = true;
             return ;
         }
         else
         {
             lblErrorMessage.Visible = false;
         }
     }
       SaveDeviceSettings();
       UpdateDevices();
}

Form_Loadイベントはライブ表示中かどうかの確認をします。もしライブ表示中であった場合、ダイアログボックスを再フォーマットして、ライブ表示中にはダイアログボックスを表示できないというメッセージがでるようにします。これはデバイスの変更が何らかの悪影響を与える可能性がある場合に警告させるためのものです。リングバッファコレクション ICImagingControl.ImageBuffersクラスライブラリリファレンスクラス>ICImagingControl>ICImagingControl.ImageBuffers Propertyはデバイスが変更になった時にリセットされます。よって、コレクション内の画像データが失われることになります。

OKボタンとCancelボタンのclickイベントを追加し、以下のコードを挿入します。

[C#]
private void cmdOK_Click( object sender, System.EventArgs e )
{
     this .Close();
}

[C#]
private void cmdCancel_Click( object sender, System.EventArgs e )
{
     RestoreDeviceSettings();
     this .Close();
}


上記のように、Form_LoadイベントはプロシージャSaveDeviceSettingsを呼び出し、 CancelButton_ClickイベントはRestoreDeviceSettingsを呼び出します。
Form_Loadイベント時に呼び出されるUpdateDevicesプロシージャがダイアログのコントロールを更新します。これに関しては後述します。
SelectedIndexChangedイベントを5つの コンボボックスに、clickイベントを2つのチェックボックスに追加します。 デバイスのコンボボックスのSelectedIndexChangedイベントにおいては選択中のデバイスが変更されると同時に全てのコンボボックス、チェックボックス、そしてSerial Numberのテキストの領域も更新されなければなりません。それは以下のコードを使って実行することができます。

[C#]
private void cboDevice_SelectedIndexChanged( object sender, System.EventArgs e )
{
     try
     {
         //  デバイスを開く
         if ( cboDevice.Enabled )
         {
             ImagingControl.Device = cboDevice.Text;
             string serial;
             if( imagingControl1.DeviceCurrent.GetSerialNumber(out serial) )
             {
                 txtSerial.Text = serial;
             }
             else
             {
                 txtSerial.Text = not_available_text;
             }
        }
         //  対応するビデオ規格、フォーマット、インプットの取得
         UpdateVideoNorms();
         UpdateInputChannels();
         UpdateFlip();
     }
     catch ( Exception ex )
     {
         MessageBox.Show( ex.Message );
     }
}

新しいデバイスが選択されると、そのシリアル番号が読みだされます。もしそれが不可能であった場合、n/aと表示されます。プロシージャUpdateVideoNorms,UpdateInputChannels,UpdateFlipがコントロールを更新します。これらについては後述します。
注:ビデオフォーマットとフレームレートに関してはUpdateVideoNormsUpdateVideoFormatに よって暗黙的に更新されます。
他のコンボボックスにおけるSelectedIndexChangedイベントもだいたい同じようなものです。 cboVideoNormコンボボックスのSelectedIndexChangedイベントはUpdateVideoFormatsプロシージャを持ち、それが選択されたビデオ規格に従ってビデオフォーマットコンボボックスを更新します。そしてcboVideoFormatコンボボックスのSelectedIndexChangedイベントは UpdateFrameRatesプロシージャを持ち、ビデオフォーマットが変更された後にフレームレートコンボボックスを更新します。 その他のコンボボックスは単に選択された値を設定します。ビデオ規格コンボボックス用のコードは次のようになります。

[C#]
private void cboVideoNorm_SelectedIndexChanged( object sender, System.EventArgs e )
{
     try
     {
         if ( cboVideoNorm.Enabled )
         {
             ImagingControl.VideoNorm = cboVideoNorm.Text;
         }
         UpdateVideoFormats();
     }
     catch ( Exception ex )
     {
         MessageBox.Show( ex.Message );
     }
}

その他のコンボボックス用のSelectedIndexChangedイベントも同じように実装されます。 ただしフレームレートコンボボックスに関しては少し例外があります。フレームレートに新しい値を割り当てる時は型変換するようにしてください。cboFrameRate.Textは文字列を返しますが ICImagingControl.DeviceFrameRateクラスライブラリリファレンスクラス>ICImagingControl>ICImagingControl.DeviceFrameRate Property は浮動小数点値が必要になるためです。
最後にチェックボックス用にclickイベントを追加します。それらは単に水平反転と垂直反転の切り替えを行います。

[C#]
private void chkFlipV_CheckedChanged( object sender, System.EventArgs e )
{
     if ( imagingControl.DeviceFlipVerticalAvailable )
     {
         imagingControl.DeviceFlipVertical = ( chkFlipV.Checked  == true );
     }
}
chkFlipH用のイベントは同じように実装されます。

アップデートプロシージャ

前述の通り、 全てのコンボボックスとチェックボックスにUpdateプロシージャがあります。コンボボックス用のUpdateプロシージャは単に有効な値を適切なコンボボックスに入れていきます。もし更新より前に選択された値がコンボボックスに残っている場合、自動的にその値を選択します。UpdateDeviceプロシージャ用のコードは以下の通りです。

[C#]
private void UpdateDevices()
{
     cboDevice.Items.Clear();
     if ( imagingControl.Devices.Length > 0 )
     {
         foreach ( object Item in ImagingControl.Devices )
         {
             cboDevice.Items.Add( Item.ToString() );
         }
         if ( imagingControl.DeviceValid )
         {
             cboDevice.SelectedItem = imagingControl.Device;
         }
         else
         {
             cboDevice.SelectedIndex = 0;
         }
         cboDevice.Enabled = true;
     }
     else
     {
         cboDevice.Items.Add( not_available_text );
         cboDevice.Enabled = false;
         cboDevice.SelectedIndex = 0;
     }
}

他のコンボボックス用のUpdateプロシージャも同様に実装されていきますが、ImagingControl.DeviceFrameRatesは浮動小数点値を持つコレクションを返すので、 UpdateFrameRatesプロシージャにおいては、コンボボックスに追加する前に型変換で文字列にしなければなりません。
UpdateFlipプロシージャは現在選択されているデバイスにおいて垂直および水平反転が可能かどうかをチェックします。可能である場合には現在の状態を設定します。

[C#]
private void UpdateFlip()
{
     if ( imagingControl.DeviceFlipHorizontalAvailable )
     {
         chkFlipH.Enabled = true;
         if ( imagingControl.DeviceFlipHorizontal )
         {
             chkFlipH.Checked  = true;
         }
         else
         {
             chkFlipH.Checked  = false;
         }
     }
     else
     {
         chkFlipH.Enabled = false;
         chkFlipH.Checked = false;
     }
     if ( imagingControl.DeviceFlipVerticalAvailable )
     {
         chkFlipV.Enabled = true;
         if ( imagingControl.DeviceFlipVertical )
         {
             chkFlipV.Checked  = true;
         }
         else
         {
             chkFlipV.Checked  = false;
         }
     }
     else
     {
         chkFlipV.Enabled = false;
         chkFlipV.Checked = false;
     }
}
//>

// ------------------------------------------------------------------------------
// UI イベント
// ------------------------------------------------------------------------------

//
// cboDevice_SelectedIndexChanged
//
// 選択されたデバイスが利用可能なインプットとビデオフォーマットを取得し、
// 各コンボボックスに情報を入力
//
//<<cboDevice
private void cboDevice_SelectedIndexChanged( object sender, System.EventArgs e )
{
     try
     {
         //  デバイスを開く
         if ( cboDevice.Enabled )
         {
             imagingControl.Device = cboDevice.Text;
             string serial;
             if( imagingControl.DeviceCurrent.GetSerialNumber(out serial) )
             {
                 txtSerial.Text = serial;
             }
             else
             {
                 txtSerial.Text = not_available_text;
             }
         }
         //  対応するビデオ規格、フォーマット、インプットを取得
         UpdateVideoNorms();
         UpdateInputChannels();
         UpdateFlip();
     }
     catch ( Exception ex )
     {
         MessageBox.Show( ex.Message );
     }
}