VCDPropertiesをリストする

新しいVCDプロパティインターフェースを使用してビデオキャプチャデバイスの全プロパティを呼び出す方法について説明します。
画像取り込みデバイスから呼び出されるプロパティは全てツリービューで表示されます。プロパティの体系自体がツリー状であるためこの表示方法が最適なものとして選択されました。ツリーの根元にあたるのが VCDPropertyItemsクラスライブラリリファレンス>クラス>VCDPropertyItems コレクションです。この中には現在の画像取り込みデバイスより提供される全 VCDPropertyItemクラスライブラリリファレンス>クラス>VCDPropertyItems が含まれています。全てのVCDPropertyItemクラスライブラリリファレンス>クラス>VCDPropertyItem が一つ以上のVCDPropertyElementクラスライブラリリファレンス>クラス>VCDPropertyElementsを持ち、さらに それぞれが一つ以上のVCDPropertyInterfaceクラスライブラリリファレンス>クラス>VCDPropertyInterfacesを持ち、それらを使ってプロパティにアクセスするようになっています。
今回のサンプルプログラムのVB.NET 、C#用のソースコードはMy Documents/IC Imaging Control 3.4内の以下ののディレクトリに格納されています。

samples\VB *\List VCDProperties
samples\C# *\List VCDProperties

プロジェクトの新規作成

新しいプロジェクトを作成し、IC imaging Controlをフォームに追加してください。プログラムを実行する前に、 はじめに: Visual Studio .NETプログラマーズガイド>Visual Studioでスタート にあるように映像デバイスの選択、入力方式、ビデオフォーマットを選択してください。もしくはデバイスを選択せずにプログラムを実行してください。その際はIC Imaging Controlによってデバイス選択のダイアログが出現します。選択をせずにダイアログを閉じた場合、プログラムはエラーメッセージを表示し、終了します。

今回のサンプルはいくつかのユーザーコントロールを使用します。それらはsamples\VB71\commonもしくはsamples\C#\commonで見つけることができます。使用する前にプロジェクトに追加してください。プロジェクトをメニューより選択し、既存項目の追加を選びます。
そして samples\VB71\commonsamples\C#\commonのフォルダを開き、次のファイルを選択します。(Switch.vb,StringCombo.vb,RangeSlider.vb,PushButton.vb,ICControlBase.vb, AbsValSlider.vb) C#を使用している場合、ファイルの拡張子は.vbでなく.cs となります。では追加ボタンの横の小さい矢印をクリックし、リンクとして追加を選択してください。 これでユーザーコントロールが使用可能となります。
フォームにボタンを2つ追加し、CaptionプロパティをSelect DeviceShow Property Pageとします。そしてそれぞれbtnSelectDevicebtnShowPageと名前を付けます。これらはプロパティページダイアログにて各デバイス設定を表示するのに使用されます。では各ユーザーコントロールあたり一つのインスタンスをフォームに追加してください。名前をそれぞれbtnPush,cboMapStrings,chkSwitch, sldAbsVal,sldRangeとします。各ユーザーコントロールはVCDPropertyInterfaceクラスライブラリリファレンス>クラス>VCDPropertyInterfaceから派生する特殊なインターフェースを表しています。

ではImage ListとTree Viewをフォームに追加します。イメージリストはツリーを視覚化するためのグラフィック要素を含んでいます。ツリービューにTreeと名前を付けます。 グラフィック要素をイメージリストに追加するにはImagesの下にあるイメージリストのプロパティウィンドウ内で ... ボタンを クリックします。では次の画像を以下の順に追加してください。(item.bmp,value.bmp,auto.bmp, button.bmp,slider.bmp,switch.bmp,combo.bmp) これら全てのビットマップファイルはこのサンプルのディレクトリ内にあります。イメージリストのModifiersプロパティをFriend(C#の場合は internal) に変更します。これでイメージリストをツリービューに追加できるようになりました。 ツリービューのプロパティImageListをイメージリストの名前として設定してください。それで完了です。

機能を追加する

ClickイベントをSelect DeviceShow Property Pageボタンに追加し、以下のコードを挿入します。

[VB.NET]
Private Sub btnSelectDevice_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
  Handles btnSelectDevice.Click
     ' デバイス設定ダイアログを表示するためにライブモードを停止する
     If IcImagingControl1.LiveVideoRunning Then
         IcImagingControl1.LiveStop()
     End If

     ' デバイス設定ダイアログ表示
     IcImagingControl1.ShowDeviceSettingsDialog()

     ' デバイスを選択しなかった場合、プログラムを終了する
     If Not IcImagingControl1.DeviceValid Then
         MessageBox.Show("No device was selected.")
         Close()
         Exit Sub
     End If

     ListAllPropertyItems()

     ' ライブモードの開始
     IcImagingControl1.LiveStart()

     ' 画像取り込みデバイスの全プロパティを検索しその一覧をツリー状に表示させる
     QueryVCDProperties()
End Sub
[C#]
private void btnSelectDevice_Click(object sender, EventArgs e)
{
     // デバイス設定ダイアログを表示するためにライブモードを停止する
     if (icImagingControl1.LiveVideoRunning)     {
         icImagingControl1.LiveStop();
     }

     // デバイス設定ダイアログ表示
     icImagingControl1.ShowDeviceSettingsDialog();

     // デバイスを選択しなかった場合、プログラムを終了する
     if (!icImagingControl1.DeviceValid)
     {
         MessageBox.Show("No device was selected.");
         this.Close();
         return;
     }

     // ライブモードの開始
     icImagingControl1.LiveStart();

     // ツリービューの初期化
     QueryVCDProperties();
}
[VB.NET]
Private Sub btnShowPage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
  Handles btnShowPage.Click
     If IcImagingControl1.DeviceValid Then
         IcImagingControl1.ShowPropertyDialog()
     End If
End Sub
[C#]
private void btnShowPage_Click(object sender, EventArgs e)
{
     if (icImagingControl1.DeviceValid)
     {
         // 組み込みのプロパティダイアログの表示
         icImagingControl1.ShowPropertyDialog();
     }
}

Form_Loadイベントを追加し次のコードを挿入してください。

[VB.NET]
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    If IcImagingControl1.DeviceValid = False Then
         ' デバイス設定ダイアログを表示
         btnSelectDevice_Click(Me, Nothing)
     End If

     If IcImagingControl1.DeviceValid = True Then

         ' ライブモードの開始
         IcImagingControl1.LiveStart()

         ' 画像取り込みデバイスの全プロパティを検索しその一覧をツリー状に表示させる
         QueryVCDProperties()
     End If
End Sub
[C#]
private void Form1_Load(object sender, EventArgs e)
{
     if (!icImagingControl1.DeviceValid)
     {
         // デバイス設定ダイアログを表示
         btnSelectDevice_Click(btnSelectDevice, new System.EventArgs());
     }

     if (icImagingControl1.DeviceValid)
     {
         ListAllPropertyItems();
         // ライブモードの開始
         icImagingControl1.LiveStart();

         // 画像取り込みデバイスの全プロパティを検索しその一覧をツリー状に表示させる
         QueryVCDProperties();
     }
}

上記のコードにあるように、btnSelectDevice_ClickForm_Loadイベントは共にプロシージャListAllPropertyItemsQueryVCDPropertiesを呼び出します。QueryVCDPropertiesは現在使用している画像取り込みデバイスのプロパティをツリー状に表示させます。さらにListAllPropertyItemsがそれらのプロパティのツリー構造をデバッグアウトプットウィンドウに表示します。デバッグアウトプットはコントロール等の他の側面を除いた純粋なVCDPropertiesの体系を表します。ではプロシージャListAllPropertyItems用のコードを見てみましょう。

[VB.NET]
Private Sub ListAllPropertyItems()
     Dim PropertyItem As TIS.Imaging.VCDPropertyItem
     Dim PropertyElement As TIS.Imaging.VCDPropertyElement
     Dim PropertyInterFace As TIS.Imaging.VCDPropertyInterface ' デフォルトのインターフェース型

     ' 各プロパティインターフェース用のインターフェース型
     Dim Range As TIS.Imaging.VCDRangeProperty
     Dim Switch As TIS.Imaging.VCDSwitchProperty
     Dim AbsoluteValue As TIS.Imaging.VCDAbsoluteValueProperty
     Dim MapString As TIS.Imaging.VCDMapStringsProperty
     Dim Button As TIS.Imaging.VCDButtonProperty

     ' 全プロパティ項目の取得
     For Each PropertyItem In IcImagingControl1.VCDPropertyItems
         System.Diagnostics.Debug.WriteLine(PropertyItem.Name)

         ' 現在のプロパティ項目の全エレメントを取得
         For Each PropertyElement In PropertyItem.Elements
             System.Diagnostics.Debug.WriteLine("    Element : " + PropertyElement.Name)

             ' 現在のプロパティエレメントの全インターフェースを取得
             For Each PropertyInterFace In PropertyElement
                System.Diagnostics.Debug.Write("        Interface ")

                 Try
                     ' 特殊インターフェースプロパティへアクセスするために現在のインターフェースを
                     ' 最適な型にキャスト
                     Select Case PropertyInterFace.InterfaceID
                         Case VCDIDs.VCDInterface_AbsoluteValue
                             AbsoluteValue = PropertyInterFace
                             System.Diagnostics.Debug.WriteLine("Absolut Value : " + AbsoluteValue.Value.ToString)  

                         Case VCDIDs.VCDInterface_MapStrings
                             MapString = PropertyInterFace
                             System.Diagnostics.Debug.WriteLine("Mapstring : " + MapString.String)

                         Case VCDIDs.VCDInterface_Switch
                             Switch = PropertyInterFace
                             System.Diagnostics.Debug.WriteLine("Switch : " + Switch.Switch.ToString)

                         Case VCDIDs.VCDInterface_Button
                             Button = PropertyInterFace
                             System.Diagnostics.Debug.WriteLine("Button")

                         Case VCDIDs.VCDInterface_Range
                             Range = PropertyInterFace
                             System.Diagnostics.Debug.WriteLine("Range : " + Range.Value.ToString)
                    End Select
                 Catch ex As System.Exception
                     System.Diagnostics.Debug.WriteLine("<error>")
                 End Try
             Next
         Next
     Next
End Sub
[C#]
private void ListAllPropertyItems()
{
     // 各プロパティインターフェース用のインターフェース型
     TIS.Imaging.VCDRangeProperty Range;
     TIS.Imaging.VCDSwitchProperty Switch;
     TIS.Imaging.VCDAbsoluteValueProperty AbsoluteValue;
     TIS.Imaging.VCDMapStringsProperty MapString;
     TIS.Imaging.VCDButtonProperty Button;

     // 全プロパティ項目の取得
    foreach (TIS.Imaging.VCDPropertyItem PropertyItem in icImagingControl1.VCDPropertyItems)
     {
         System.Diagnostics.Debug.WriteLine(PropertyItem.Name);

         // 現在のプロパティ項目の全エレメントを取得
        foreach (TIS.Imaging.VCDPropertyElement PropertyElement in PropertyItem.Elements)
         {
             System.Diagnostics.Debug.WriteLine("    Element : " + PropertyElement.Name);

             // 現在のプロパティエレメントの全インターフェースを取得
             foreach (TIS.Imaging.VCDPropertyInterface PropertyInterFace in PropertyElement)
             {
                 System.Diagnostics.Debug.Write("        Interface ");

                 try
                 {
                     // 特殊インターフェースプロパティへアクセスするために現在のインターフェースを
                     // 最適な型にキャスト

                     if (PropertyInterFace.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_AbsoluteValue)
                     {
                         AbsoluteValue = (TIS.Imaging.VCDAbsoluteValueProperty)PropertyInterFace;
                         System.Diagnostics.Debug.Write("Absolut Value : ");
                         System.Diagnostics.Debug.WriteLine(AbsoluteValue.Value.ToString());
                     }
                          else if ( PropertyInterFace.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_MapStrings )
                     {
                             MapString = (TIS.Imaging.VCDMapStringsProperty)PropertyInterFace;
                             System.Diagnostics.Debug.Write("Mapstring : ");
                            System.Diagnostics.Debug.WriteLine(MapString.String);
                    }
                     else if ( PropertyInterFace.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Switch )
                     {
                             Switch = (TIS.Imaging.VCDSwitchProperty)PropertyInterFace;
                             System.Diagnostics.Debug.Write("Switch : ");
                             System.Diagnostics.Debug.WriteLine(Switch.Switch.ToString());
                      }
                      else if (PropertyInterFace.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Button)
                      {
                          Button = (TIS.Imaging.VCDButtonProperty)PropertyInterFace;
                          System.Diagnostics.Debug.WriteLine("Button");
                      }
                      else if (PropertyInterFace.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Range)
                      {
                          Range = (TIS.Imaging.VCDRangeProperty)PropertyInterFace;
                          System.Diagnostics.Debug.Write("Range : ");
                          System.Diagnostics.Debug.WriteLine(Range.Value.ToString());
                      }

                 }
                 catch (Exception ex)
                 {
                     System.Diagnostics.Debug.WriteLine("<error>");
                 }
             }
         }
     }
}

上のコードにある3つのネストされたFor EachループはVCDPropertiesの3構造を反映しているものです。 最初のループは利用可能な全VCDPropertyItemクラスライブラリリファレンス>クラス>VCDPropertyItemsをカバーしその名前をデバッグアウトプットに表示します。 2つ目のループは各項目ごとに、利用可能な全 VCDPropertyElementクラスライブラリリファレンス>クラス>VCDPropertyElementsを表示します。そして3つ目のループがエレメントの提供する全インターフェースの型を表示します。インターフェースは詳細の程度によってソートされます。最も詳細なものは "AbsoluteValue(絶対値)" インターフェースでそれに続くのが "MapStrings(マップストリングス)" インターフェース、"スイッチ" と"ボタン" インターフェースは詳細なインターフェースですがトリガーのオンとオフなどシンプルな機能を提供するものです。 "Range(レンジ)" インターフェースは最も汎用的ですが、表す値に意味はありません。例えば "Brightness" の値の範囲は 0 から 255ですが、0 と 255 のどちらが最大の輝度値を表すかはわかりません。
QueryVCDPropertiesプロシージャを見てみましょう。このプロシージャは適切な値をツリービューで表示します。このプロシージャのコードは以下の通りです。

[VB.NET]
Private Sub QueryVCDProperties()
     ' ツリーを完全に消去
     Tree.Nodes.Clear()

     ' ルートノードの作成
     Dim root As New TreeNode("VCDPropertyItems")
     root.Tag = Nothing
     Tree.Nodes.Add(root)

     ' VCDPropertyItemsをクエリー、ツリーの形成
     QueryVCDPropertyItems(root, IcImagingControl1.VCDPropertyItems)

     ' ツリーをすべて広げて確認
     root.ExpandAll()
End Sub
[C#]
private void QueryVCDProperties()
{
     // ツリーを完全に消去
     Tree.Nodes.Clear();

     // ツリーの形成
     TreeNode root = new TreeNode("VCDPropertyItems");
     Tree.Nodes.Add(root);

     QueryVCDPropertyItems(root, icImagingControl1.VCDPropertyItems);

     root.ExpandAll();
     Tree.SelectedNode = root;
}

上のプロシージャはツリービューを消去して新しいルートノードを作成します。ルートノードのCaptionプロパティをVCDPropertyItemsとします。それからプロシージャQueryVCDPropertyItemsが利用可能な全プロパティ項目を挿入します。そのプロシージャは以下のようになります。

[VB.NET]
Private Sub QueryVCDPropertyItems(ByVal ParentNode As TreeNode,
  ByVal PropertyItems As TIS.Imaging.VCDPropertyItems)
     ' 全VCDPropertyItemsをツリーコントロールに挿入
     For Each item As TIS.Imaging.VCDPropertyItem In PropertyItems
         ' プロパティ項目のための新しいツリーノードを作成
         ' 項目識別子文字列はツリーノードのタグプロパティに格納
         Dim newNode As New TreeNode(item.Name, 0, 0)
         newNode.Tag = Nothing

         ParentNode.Nodes.Add(newNode)

         ' プロパティ項目のエレメントをクエリーする
         QueryVCDPropertyElements(newNode, item)
       Next
End Sub
[C#]
private void QueryVCDPropertyItems(TreeNode pp, TIS.Imaging.VCDPropertyItems props)
{
     // 全VCDPropertyItemsをツリーコントロールに挿入
     foreach (TIS.Imaging.VCDPropertyItem item in props)
     {
         // プロパティ項目のための新しいツリーノードを作成
         TreeNode newNode = new TreeNode(item.Name, 0, 0);
         //               
         newNode.Tag = item.ItemID;
         newNode.Tag = null;
         pp.Nodes.Add(newNode);

         QueryVCDPropertyElements(newNode, item);
     }
}

QueryVCDPropertyItemsは利用可能な全てのプロパティ項目の実行を繰り返し、毎回新しいノードを作成します。これらのノードは全てルートノードの子ノードです。VCDPropertyItemクラスライブラリリファレンス>クラス>VCDPropertyItem の名前 (e.g. "Brightness", "Gain" or "Exposure") はそのノードのTextプロパティに割り当てられます。Nothing(C#であればnull) はノードのtagプロパティに割り当てられます。そしてQueryVCDPropertyElementsが新しいノード用に呼び出されます。QueryVCDPropertyElementsは以下の通りです。

[VB.NET]
Private Sub QueryVCDPropertyElements(ByVal ParentNode As TreeNode,
  ByVal PropertyItem As TIS.Imaging.VCDPropertyItem)
     ' ディスプレイ名を作成
     Dim name As String
     Dim Image As Integer
     Dim Element As TIS.Imaging.VCDPropertyElement
       For Each Element In PropertyItem.Elements
         ' プロパティエレメント名を作成
         Select Case Element.ElementID
             Case VCDIDs.VCDElement_Value
                name = "VCDElement_Value"
                Image = 1
             Case VCDIDs.VCDElement_Auto
                 name = "VCDElement_Auto"
                 Image = 2
             Case VCDIDs.VCDElement_OnePush
                 name = "VCDElement_OnePush"
                 Image = 3
             Case VCDIDs.VCDElement_WhiteBalanceRed
                 name = "VCDElement_WhiteBalanceRed"
                 Image = 4
             Case VCDIDs.VCDElement_WhiteBalanceBlue
                 name = "VCDElement_WhiteBalanceBlue"
                 Image = 4
             Case Else
                 name = "Other Element ID"
                 Image = 4
         End Select

         ' エレメント用のノードを作成し、ツリーコントロールに挿入
         ' 項目とエレメントの識別文字列をツリーノードのタグプロパティに格納
         Dim newNode As New TreeNode(name + ": " + Element.Name, Image, Image)
         newNode.Tag = Nothing

         ParentNode.Nodes.Add(newNode)

         ' プロパティエレメントのインターフェースをクエリー
         QueryVCDPropertyInterface(newNode, Element)
     Next
End Sub
[C#]
private void QueryVCDPropertyElements(TreeNode pp, TIS.Imaging.VCDPropertyItem item)
{
     TreeNode newNode = null;

     foreach (TIS.Imaging.VCDPropertyElement elem in item.Elements)
     {
        newNode = new TreeNode(elem.ElementID+": '" + elem.Name + "'", 1, 1);

        if ( elem.ElementID == TIS.Imaging.VCDIDs.VCDElement_Value )
             newNode = new TreeNode("VCDElement_Value: '" + elem.Name + "'", 1, 1);
        else if ( elem.ElementID == TIS.Imaging.VCDIDs.VCDElement_Auto )
             newNode = new TreeNode("VCDElement_Auto: '" + elem.Name + "'", 2, 2);
        else if ( elem.ElementID == TIS.Imaging.VCDIDs.VCDElement_OnePush )
             newNode = new TreeNode("VCDElement_OnePush: '" + elem.Name + "'", 3, 3);
         else if ( elem.ElementID == TIS.Imaging.VCDIDs.VCDElement_WhiteBalanceRed )
             newNode = new TreeNode("VCDElement_WhiteBalanceRed: '" + elem.Name + "'", 4, 4);
         else if ( elem.ElementID == TIS.Imaging.VCDIDs.VCDElement_WhiteBalanceBlue )
             newNode = new TreeNode("VCDElement_WhiteBalanceBlue: '" + elem.Name + "'", 4, 4);
         else
             newNode = new TreeNode("Other Element ID: '" + elem.Name + "'", 4, 4);

         newNode.Tag = null;
         pp.Nodes.Add(newNode);

         // 全インターフェースを挿入
         QueryVCDPropertyInterface(newNode, elem);
     }
}

QueryVCDPropertyElementsは利用可能なエレメントの実行を繰り返し、そのすべてに対して、新しいノードを作成します。これらのノードは全てルートノードの子ノードで、これらのVCDPropertyElementクラスライブラリリファレンス>クラス>VCDPropertyElements が属するVCDPropertyItemクラスライブラリリファレンス>クラス>VCDPropertyItem を表します。Selectブロック (C#であればswitchブロック) はそのノードに最適なグラフィックツリーエレメントを決定し、そのベースネームをエレメントの型に応じて設定します。VCDPropertyElementクラスライブラリリファレンス>クラス>VCDPropertyElement の名前(e.g. "Value", "Auto" or "Enable") はベースネームに追加され、ノードのTextプロパティに割り当てられます。Nothing(C#であれば null)はノードのtagプロパティに割り当てられ、QueryVCDPropertyInterfaceが新しいノード用に呼び出されます。QueryVCDPropertyInterfaceは以下の通りです。

[VB.NET]
Private Sub QueryVCDPropertyInterface(ByVal ParentNode As TreeNode,
  ByVal PropertyElement As TIS.Imaging.VCDPropertyElement)
     Dim Name As String
     Dim image As Integer
     Dim Itf As TIS.Imaging.VCDPropertyInterface

     ' 渡されたVCDPropertyElementの全VCDPropertyInterfacesの実行をを繰り返し、
     ' ツリーコントロールに挿入
     For Each Itf In PropertyElement
         ' 適切なインターフェースネームを作成.
         Select Case Itf.InterfaceID
             Case VCDIDs.VCDInterface_AbsoluteValue
                 Name = "AbsoluteValue"
                 image = 4
             Case VCDIDs.VCDInterface_MapStrings
                 Name = "MapStrings"
                 image = 6
             Case VCDIDs.VCDInterface_Range
                 Name = "Range"
                 image = 4
             Case VCDIDs.VCDInterface_Switch
                 Name = "Switch"
                 image = 5
             Case VCDIDs.VCDInterface_Button
                 Name = "Button"
                 image = 3
         End Select

         ' ノードの挿入
         ' 項目、エレメント、インターフェースの識別文字列をツリーノードのタグプロパティに格納
         Dim newNode As New TreeNode(Name, image, image)
         newNode.Tag = Itf.Parent.Parent.ItemID + ":" + Itf.Parent.ElementID + ":" + Itf.InterfaceID

         ParentNode.Nodes.Add(newNode)
     Next
End Sub
[C#]
private void QueryVCDPropertyInterface(TreeNode pp, TIS.Imaging.VCDPropertyElement elem)
{
     TreeNode newNode = null;
       foreach (TIS.Imaging.VCDPropertyInterface itf in elem)
     {
         newNode = new TreeNode(itf.InterfaceID, 4, 4);

         if ( itf.InterfaceID ==  TIS.Imaging.VCDIDs.VCDInterface_AbsoluteValue )
           newNode = new TreeNode("AbsoluteValue", 4, 4);
         else if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_MapStrings )
            newNode = new TreeNode("MapStrings", 6, 6);
         else if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Range )
             newNode = new TreeNode("Range", 4, 4);
          else if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Switch )
             newNode = new TreeNode("Switch", 5, 5);                   else if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Button )
             newNode = new TreeNode("Button", 3, 3);

          // Tag プロパティがノードでインターフェースを保持
         newNode.Tag = itf.Parent.Parent.ItemID + ":" + itf.Parent.ElementID + ":" + itf.InterfaceID;
         pp.Nodes.Add(newNode);
     }
}

QueryVCDPropertyInterfaceは利用可能なエレメントのインターフェースの実行を繰り返し、そのすべてに対して新しいノードを作成します。これらのノードは全てルートノードの子ノードで、これらVCDPropertyInterfaceクラスライブラリリファレンス>クラス>VCDPropertyInterface が属するVCDPropertyElementクラスライブラリリファレンス>クラス>VCDPropertyElementを表します。Selectブロック (C#であれば switchブロック) はそのノードに最適なグラフィックツリーエレメントを決定し、そのベースネームをエレメントの型に応じて設定します。そしてその名前はノードのTextプロパティに割り当てられます。インターフェースパスは itemID, elementID, interfaceID から構成されノードのtagプロパティに割り当てられます。インターフェースノードはツリーの葉の部分の形成します。

VCDPropertyへのアクセスと調整

ツリーは完成したので、プロパティにアクセスしたいと思います。ツリービューにAfterSelectイベントを追加して次のコードを挿入します。

[VB.NET]
Private Sub Tree_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.
TreeViewEventArgs) Handles Tree.AfterSelect

     ' Tag プロパティが空の場合、リーフノードは選択されません
     If Tree.SelectedNode.Tag Is Nothing Then Exit Sub

     If Not RangeCtrl Is Nothing Then RangeCtrl.Dispose()
     If Not SwitchCtrl Is Nothing Then SwitchCtrl.Dispose()
     If Not MapStringsCtrl Is Nothing Then MapStringsCtrl.Dispose()
     If Not ButtonCtrl Is Nothing Then ButtonCtrl.Dispose()
     If Not AbsValCtrl Is Nothing Then AbsValCtrl.Dispose()

     Dim itfPath As String = Tree.SelectedNode.Tag
     Dim itf As TIS.Imaging.VCDPropertyInterface = IcImagingControl1.VCDPropertyItems.FindInterface(itfPath)

      If Not itf Is Nothing Then
         itf.Update()

         ' 選択されたインターフェース型に対応する
         ' コントロールグループを表示し初期化
         Select Case itf.InterfaceID
             Case VCDIDs.VCDInterface_AbsoluteValue
                 ShowAbsoluteValueControl(itf)

             Case VCDIDs.VCDInterface_MapStrings
                 ShowComboBoxControl(itf)

             Case VCDIDs.VCDInterface_Range
                 ShowRangeControl(itf)

             Case VCDIDs.VCDInterface_Switch
                 ShowSwitchControl(itf)

             Case VCDIDs.VCDInterface_Button
                 ShowButtonControl(itf)

           End Select

       End If

  End Sub
[C#]
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
     // Tag プロパティが空の場合、リーフノードは選択されません
     if (Tree.SelectedNode.Tag == null)
     {
         return;
     }
       // 全コントロールグループを隠す
     if (RangeCtrl != null) RangeCtrl.Dispose();
     if (SwitchCtrl != null) SwitchCtrl.Dispose();
     if (MapStringsCtrl != null) MapStringsCtrl.Dispose();
     if (ButtonCtrl != null) ButtonCtrl.Dispose();
     if (AbsValCtrl != null) AbsValCtrl.Dispose();

     string itfPath = Tree.SelectedNode.Tag.ToString();
     TIS.Imaging.VCDPropertyInterface itf = icImagingControl1.VCDPropertyItems.FindInterface(itfPath);

     if (itf != null)
     {
         itf.Update();
         // 選択されたインターフェース型に対応する
         // コントロールグループを表示し初期化
         if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_AbsoluteValue )
              ShowAbsoluteValueControl(itf);
         else if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_MapStrings)
             ShowComboBoxControl(itf);
         else if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Range)
             ShowRangeControl(itf);
         else if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Switch)
             ShowSwitchControl(itf);
         else if ( itf.InterfaceID == TIS.Imaging.VCDIDs.VCDInterface_Button)
             ShowButtonControl(itf);
     }
}

これでなぜインターフェースノードのタグがインターフェースパスを格納するかがはっきりしました。インターフェースノードをクリックすると、フォームに最適なコントロールが現れ、プロパティの設定を調整できるようになります。正確なインターフェースを取得する為にFindInterface メソッドが使用されます。FindInterface はインターフェースパス(もしくはGUID)をパラメータとして必要とします。Selectブロック (C#であれば switch ブロック) が目的のインターフェースに最適なユーザーコントロールを与え各 "Show%%" プロシージャを呼び出します。 これらのプロシージャはユーザーコントロールの"Visible" プロパティをTrueに設定し、特定のプロパティの設定を調整できるようにします。ShowAbsoluteValueControlプロシージャの実装方法には以下のような例があります。

[VB.NET]
Private Sub ShowAbsoluteValueControl(ByVal itf As TIS.Imaging.VCDPropertyInterface)
     AbsValCtrl = New AbsValSlider()
     CtrlFrame.Controls.Add(AbsValCtrl)
     AbsValCtrl.SetBounds(20, 20, 500, 27)
     AbsValCtrl.AssignItf(itf)
     CtrlFrame.Text = itf.Parent.Parent.Name + ": " + itf.Parent.Name ' プロパティ項目名
End Sub
[C#]
private void ShowAbsoluteValueControl(TIS.Imaging.VCDPropertyInterface itf)
{
     TIS.Imaging.VCDAbsoluteValueProperty AbsValItf = (TIS.Imaging.VCDAbsoluteValueProperty)itf;
     AbsValCtrl = new AbsValSlider();
     CtrlFrame.Controls.Add(AbsValCtrl);
     AbsValCtrl.SetBounds(20, 20, 500, 27);
     AbsValCtrl.AssignItf(AbsValItf);
     CtrlFrame.Text = "Absolute Value";
}

他のユーザーコントロール用のプロシージャも同じようにして実装できます。(VB.NET の例で省略されている最後の一行を除く)