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

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

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

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

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

[VB.NET]
Dim DeviceDialog As New frmDeviceSettings

DeviceDialog.ImagingControl = IcImagingControl1
DeviceDialog.ShowDialog()  

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

ダイアログの作成

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

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

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

[VB.NET]
Public ImagingControl As TIS.Imaging.ICImagingControl
Private  DeviceState As String
Const NOT_AVAILABLE = "n/a"
[C#]
public TIS.Imaging.ICImagingControl ImagingControl;
private string DeviceState;
private const string NOT_AVAILABLE = "n/a";

ではForm_Load イベントを追加し、以下のコードを挿入してください。

[VB.NET]
Private Sub frmDeviceSettings_Load( ByVal sender As System.Object, ByVal e As System.EventArgs)
 Handles MyBase .Load
     If ImagingControl.DeviceValid Then
         If ImagingControl.LiveVideoRunning Then
            lblErrorMessage.Text =
              "The device settings dialog is not available while the live video is running.\n\nStop the live video first."
            lblErrorMessage.AutoSize = False
            lblErrorMessage.Padding = New Padding(8)
            lblErrorMessage.SetBounds(0, 0, 100, cmdOK.Top)
            lblErrorMessage.Dock = DockStyle.Top
            lblErrorMessage.Visible = True
            Exit Sub
         Else
             lblErrorMessage.Visible = False
         End If
     End If

      SaveDeviceSettings()

      UpdateDevices()
End Sub
[C#]
private void frmDeviceSettings_Load( object sender, EventArgs e )
{
     if ( ImagingControl.DeviceValid )
     {
         if ( ImagingControl.LiveVideoRunning )
         {
             lblErrorMessage.Text =
               "The device settings dialog is not available while the live video is running.\n\nStop the live video first.";
             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イベントを追加し、以下のコードを挿入します。

[VB.NET]
Private Sub cmdOK_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles  cmdOK.Click
     Me.Close ()
End Sub
[C#]
private void cmdOK_Click( object sender, System.EventArgs e )
{
     this .Close();
}
[VB.NET]
Private Sub cmdCancel_Click( ByVal sender As System.Object, ByVal e As System.EventArgs)
 Handles  cmdCancel.Click
     RestoreDeviceSettings()
     Me.Close ()
End Sub
[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のテキストの領域も更新されなければなりません。それは以下のコードを使って実行することができます。

[VB.NET]
Private Sub cboDevice_SelectedIndexChanged( ByVal sender As System.Object, ByVal e As System.EventArgs)
  Handles  cboDevice.SelectedIndexChanged
     Dim Serial As String = ""

       Try
         'デバイスを有効にする
         If cboDevice.Enabled Then

             Dim Item As Object
             Dim index As Integer
             index = 0

             ImagingControl.Device = cboDevice.Text
             txtSerial.Text = NOT_AVAILABLE

             For Each Item In ImagingControl.Devices
                 If Item.Name = cboDevice.Text Then
                     If ImagingControl.Devices(index).GetSerialNumber(Serial) Then
                         txtSerial.Text = Serial
                         Exit For
                     End If
                 End If
                 index = index + 1
             Next

             ' 対応するビデオ規格、フォーマット、インプットの取得
             UpdateVideoNorms()
             UpdateInputChannels()
             UpdateFlip()

         End If

     Catch  ex As System.Exception
         MessageBox.Show(ex.Message)
     End Try
End Sub
[C#]
private void cboDevice_SelectedIndexChanged( object sender, System.EventArgs e )
{
     string Serial = "";

     try
     {
         // デバイスを有効にする
         if ( cboDevice.Enabled )
         {
             int index = 0;
             ImagingControl.Device = cboDevice.Text;

             txtSerial.Text = NOT_AVAILABLE;

             foreach ( object Item in ImagingControl.Devices )
             {
                 if ( Item.ToString() == cboDevice.Text )
                 {
                     if ( ImagingControl.Devices[index].GetSerialNumber( out Serial ) )
                     {
                         txtSerial.Text = Serial;
                         break;
                     }
                 }
                 index++;
             }
         }
         // 対応するビデオ規格、フォーマット、インプットの取得
         UpdateVideoNorms();
         UpdateInputChannels();
         UpdateFlip();
     }
     catch ( Exception ex )
     {
         MessageBox.Show( ex.Message );
     }
}

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

[VB.NET]
Private Sub cboVideoNorm_SelectedIndexChanged( ByVal sender As System.Object, ByVal e As System.EventArgs)
  Handles  cboVideoNorm.SelectedIndexChanged
     Try
         If cboVideoNorm.Enabled Then
             ImagingControl.VideoNorm = cboVideoNorm.Text
         End If

         UpdateVideoFormats()

     Catch  ex As System.Exception
         MessageBox.Show(ex.Message)
     End Try
End Sub
[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イベントを追加します。それらは単に水平反転と垂直反転の切り替えを行います。

[VB.NET]
Private Sub chkFlipV_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles  chkFlipV.Click
     If ImagingControl.DeviceFlipVerticalAvailable Then
         ImagingControl.DeviceFlipVertical = (chkFlipV.Checked  = True)
     End If
End Sub
[C#]
private void chkFlipV_Checked Changed( object sender, System.EventArgs e )
{
     if ( ImagingControl.DeviceFlipVerticalAvailable )
     {
         ImagingControl.DeviceFlipVertical = ( chkFlipV.Checked  == true );
     }
}

chkFlipH用のイベントは同じように実装されます。

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

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

[VB.NET]
Private Sub UpdateDevices()
     cboDevice.Items.Clear()
     If ImagingControl.Devices.Length > 0 Then
        Dim Item As Object

        For Each Item In ImagingControl.Devices
             cboDevice.Items.Add(Item.ToString())
        Next

        If ImagingControl.DeviceValid Then
             cboDevice.SelectedItem = ImagingControl.Device
        Else
             cboDevice.SelectedIndex = 0
        End If
        cboDevice.Enabled = True
     Else
         cboDevice.Items.Add(NOT_AVAILABLE)
         cboDevice.Enabled = False
         cboDevice.SelectedIndex = 0
     End If
End Sub
[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 );
         cboDevice.Enabled = false;
         cboDevice.SelectedIndex = 0;
     }
}

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

[VB.NET]
Private Sub UpdateFlip()
     If ImagingControl.DeviceFlipHorizontalAvailable Then
         chkFlipH.Enabled = True
         If ImagingControl.DeviceFlipHorizontal Then
             chkFlipH.Checked  = True
         Else
             chkFlipH.Checked  = False
         End If
     Else
         chkFlipH.Enabled = False
         chkFlipH.Checked  = False
     End If
     If ImagingControl.DeviceFlipVerticalAvailable Then
         chkFlipV.Enabled = True
         If ImagingControl.DeviceFlipVertical Then
             chkFlipV.Checked  = True
         Else
             chkFlipV.Checked  = False
         End If
     Else
         chkFlipV.Enabled = False
         chkFlipV.Checked  = False
     End If
End Sub
[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 )
{
     string Serial = "";

     try
     {
         // デバイスを有効にする
         if ( cboDevice.Enabled )
         {
             int index = 0;
             ImagingControl.Device = cboDevice.Text;
               txtSerial.Text = NOT_AVAILABLE;
              foreach ( object Item in ImagingControl.Devices )
             {
                if ( Item.ToString() == cboDevice.Text )
                {
                    if ( ImagingControl.Devices[index].GetSerialNumber( out Serial ) )
                    {
                        txtSerial.Text = Serial;
                        break;
                     }
                 }
                 index++;
             }
         }
         // 対応するビデオ規格、フォーマット、インプットを取得
         UpdateVideoNorms();
         UpdateInputChannels();
         UpdateFlip();
     }
     catch ( Exception ex )
     {
         MessageBox.Show( ex.Message );
     }
}