This chapter shows you how to retrieve all properties of a video capture device using the new VCD property interface.
All properties that are retrieved from the video capture device are displayed in a TreeView. The TreeView was chosen, because it perfectly matches the organization of the properties, since they establish a tree structure. The root of the tree is the VCDPropertyItems collection. The collection contains all VCDPropertyItems that are provided by the current video capture device. Every VCDPropertyItem has one or more VCDPropertyElements, which have one or more VCDPropertyInterfaces that are used to access the property.
The source code for this sample program is contained in the samples\VB6\List VCD Properties sample source directory.
Create a new project and add IC Imaging Control to the form. Before you run the program, select the video device, input and video format as shown in the First Steps in Visual Basic 6 chapter. Alternatively, run the program without selecting a device. In this case, the program shows the device selection dialog provided by IC Imaging Control. If you close this dialog without making a selection, the program displays an error message and terminate.
This sample uses the module VCDPropertyID.bas and some user controls. They can be found in the directory samples\VB6\common. Before you can use them, you have to add them to the project. To add the module, select Project from the menu and then choose Add Module. In the dialog click on the Existing tab and browse to the samples\VB6\common folder. Select VCDPropertyID.bas and click Open. To include the user controls, select Project from the menu and choose Add User Control. Click on the Existing tab and browse to the samples\VB6\common folder. Select AbsValSlider.ctl and click the Open button. The other user controls, namely PushButton.ctl, RangeSlider.ctl, StringCombo.ctl and Switch.ctl are included the same way. Now you are ready to use the user controls.
Add 2 buttons to the form, name them btnSelectDevice and btnShowPage and label them Select Device and Show Property Page. They will be used to show the device settings and property page dialog provided by IC Imaging Control. Now add one instance of every user control to the form. Give them the same name as the control itself, e.g. name the AbsValSlider AbsValSlider. Each of the user controls represents a special type of interface derived from VCDPropertyInterface.
Now add an image list and a tree view to the form. The image list will contain the graphical elements that are used to visualize the tree. Therefore, it is very important to add the image list before the tree view, because otherwise it is not possible to bind the image list to the tree view. Name the image list TreeImageList and the tree view Tree. Using the right mouse button, click on the image list and select Properties from the context menu. Under the General tab choose the 16x16 format and make sure that UseMaskColor is checked. Now switch to the Color tab and set both, the Back- and the MaskColor to white. Finally switch to the "Images" tab and add the following images in the given order: slider.png, switch.png, button.png, combo.png, value.png, auto.png and item.png. All these bitmap files can be found in the directory of this sample. Now, the image list can be added to the tree view. To do so, right click button, on the tree view. Select Properties from the context menu and select the General tab in the properties dialog. Change the Style to 5 - tvwTreelinesPictureText and set ImageList to TreeImageList. This will bind the image list to the tree view.
Add the Click events for the Select Device and Show Property Page buttons and insert the following code:
Private Sub btnSelectDevice_Click() ' The device settings dialog needs the live mode to be stopped. If ICImagingControl1.LiveVideoRunning Then ICImagingControl1.LiveStop End If ' Show the device settings dialog ICImagingControl1.ShowDeviceSettingsDialog ' If no device was selected, exit the program. If Not ICImagingControl1.DeviceValid Then MsgBox "No device was selected." End End If ListAllPropertyItems ' Start live mode ICImagingControl1.LiveStart ' Query all properties of the video capture device and list ' them in a tree control. QueryVCDProperties End Sub
Private Sub btnShowPage_Click() If ICImagingControl1.DeviceValid Then ICImagingControl1.ShowPropertyDialog End If End Sub
Now add a Form_Load event and insert the code below:
Private Sub Form_Load() If ICImagingControl1.DeviceValid = False Then ' Show the device settings dialog. btnSelectDevice_Click End If If ICImagingControl1.DeviceValid = True Then ListAllPropertyItems ' Start live mode. ICImagingControl1.LiveStart ' Query all properties of the video capture device and list ' them in a tree control. QueryVCDProperties End If End Sub
As you can see in the code above, the btnSelectDevice_Click and the Form_Load event both call the procedures ListAllPropertyItems and QueryVCDProperties. QueryVCDProperties fills the tree view with the properties of the current video capture device. Additionally, ListAllPropertyItems prints the tree structure of those properties to the debug output window. The debug output shows you the pure organization of the VCDProperties without taking care of other aspects like controls. Let's have a look at the code for the procedure ListAllPropertyItems:
Private Sub ListAllPropertyItems() On Error Resume Next Dim PropertyItem As VCDPropertyItem Dim PropertyElement As VCDPropertyElement Dim PropertyInterFace As VCDPropertyInterface ' Default interface type. ' Interface types for the different property interfaces. Dim Range As VCDRangeProperty Dim Switch As VCDSwitchProperty Dim AbsoluteValue As VCDAbsoluteValueProperty Dim MapString As VCDMapStringsProperty Dim Button As VCDButtonProperty ' Get all property items For Each PropertyItem In ICImagingControl1.VCDPropertyItems Debug.Print PropertyItem.name ' Get all property elements of the current property item. For Each PropertyElement In PropertyItem.Elements Debug.Print " Element : " + PropertyElement.name ' Get all interfaces of the current property element. For Each PropertyInterFace In PropertyElement Debug.Print " Interface "; ' Cast the current interface into the apropriate type to access ' the special interface properties. Select Case PropertyInterFace.InterfaceID Case VCDInterface_AbsoluteValue: Set AbsoluteValue = PropertyInterFace Debug.Print "Absolut Value : " + Str(AbsoluteValue.Value) Case VCDInterface_MapStrings: Set MapString = PropertyInterFace Debug.Print "Mapstring : " + MapString.String Case VCDInterface_Switch: Set Switch = PropertyInterFace Debug.Print "Switch : "; Debug.Print Switch.Switch Case VCDInterface_Button: Set Button = PropertyInterFace Debug.Print "Button" Case VCDInterface_Range: Set Range = PropertyInterFace Debug.Print "Range : "; Debug.Print Str(Range.Value) End Select Next Next Next End Sub
The three nested For Each loops in the code above reflects the tree structure of the VCDProperties. The first loop covers all available VCDPropertyItems and prints their names to the debug output. For each item, the second loop prints out all available VCDPropertyElements. The third loop prints out all types of interfaces that the element provides. Please note that the interfaces are sorted according to their extend of detail. The most detailed one is the "AbsoluteValue" interface, followed by the "MapStrings" interface. "Switch" and "Button" are detailed interfaces providing simple functionality: toggle On/Off, trigger. The "Range" interface is the most generic one, but does not provide a meaning for the values that represents. For example the "Brightness" range may be from 0 to 255. There is no way to tell, whether 0 or 255 is the maximum brightness value.
Now let's have a look at the QueryVCDProperties procedure. This procedure fills the tree view with appropriate values. The code for this procedure looks as follows:
Private Sub QueryVCDProperties() ' Erase the complete tree. Tree.Nodes.Clear ' Create the root node. Dim root As Node Set root = Tree.Nodes.Add(, , , "VCDPropertyItems") ' Query the VCDPropertyItems and fill the tree. QueryVCDPropertyItems root, ICImagingControl1.VCDPropertyItems ' Make sure the tree is expanded. root.Expanded = True End Sub
The procedure above clears the tree view and creates a new root node. The root node is labeled VCDPropertyItems. Then the procedure QueryVCDPropertyItems inserts all available property items. This procedure looks as follows:
Private Sub QueryVCDPropertyItems(ParentNode As Node, PropertyItems As VCDPropertyItems) Dim PropertyItem As VCDPropertyItem ' Iterate through all VCDPropertyItems and insert them into the tree control. For Each PropertyItem In PropertyItems ' Create a new tree node for the property item. ' The item identifier string is stored in the key ' property of the tree node. Dim newNode As Node Set newNode = Tree.Nodes.Add(ParentNode, tvwChild, "", PropertyItem.name, 7, 7) ' Now query the elements of the property item. QueryVCDPropertyElements newNode, PropertyItem newNode.Expanded = True Next End Sub
QueryVCDPropertyItems iterates through all available property items. For every item, it creates a new node. All of these nodes are direct children of the root node. The name of the VCDPropertyItem (e.g. "Brightness", "Gain" or "Exposure") is assigned to the Text property of the node. An empty string is assigned to the key property of the node. Then, QueryVCDPropertyElements is called for the new node. QueryVCDPropertyElements looks as follows:
Private Sub QueryVCDPropertyElements(ParentNode As Node, PropertyItem As VCDPropertyItem) ' generate a display name Dim name As String Dim Image As Integer Dim Element As VCDPropertyElement For Each Element In PropertyItem.Elements ' Create a name for the property element. Select Case Element.ElementID Case VCDElement_Value: name = "VCDElement_Value" Image = 5 Case VCDElement_Auto: name = "VCDElement_Auto" Image = 6 Case VCDElement_OnePush: name = "VCDElement_OnePush" Image = 3 Case VCDElement_WhiteBalanceRed: name = "VCDElement_WhiteBalanceRed" Image = 5 Case VCDElement_WhiteBalanceBlue: name = "VCDElement_WhiteBalanceBlue" Image = 5 Case Else name = "Other Element ID" Image = 5 End Select ' Create a tree node for the element and insert it into the tree control. ' The item and element identifier strings are stored in the key property ' of the tree node. Dim newNode As Node Set newNode = Tree.Nodes.Add(ParentNode, tvwChild, "", name + ": " + Element.name, Image, Image) ' Now query the interfaces of the property element. QueryVCDPropertyInterface newNode, Element ' Make sure the tree is expanded newNode.Expanded = True Next End Sub
QueryVCDPropertyElements iterates through all available elements. For every element, it creates a new node. All of these nodes are children of the node which represents the VCDPropertyItem to which these VCDPropertyElements belong. The Select block determines the appropriate graphical tree element for the node and sets its base name, depending on the type of the element. The name of the VCDPropertyElement (e.g. "Value", "Auto" or "Enable") is added to the base name and then assigned to the Text property of the node. An empty string is assigned to the key property of the node. Then, QueryVCDPropertyInterface is called for the new node. QueryVCDPropertyInterface looks as follows:
Private Sub QueryVCDPropertyInterface(ParentNode As Node, PropertyElement As VCDPropertyElement) Dim name As String Dim Image As Integer Dim InterFace As VCDPropertyInterface ' Iterate through all VCDPropertyInterfaces of the passed VCDPropertyElement ' and insert them into the tree control. For Each InterFace In PropertyElement ' Create an appropriate interface name. Select Case InterFace.InterfaceID Case VCDInterface_AbsoluteValue: name = "AbsoluteValue" Image = 1 Case VCDInterface_MapStrings: name = "MapStrings" Image = 4 Case VCDInterface_Range: name = "Range" Image = 1 Case VCDInterface_Switch: name = "Switch" Image = 2 Case VCDInterface_Button: name = "Button" Image = 3 End Select ' Insert the node. ' The element and interface identifier strings are stored in the key property ' of the tree node. The ParentNode.Key contains the item and the element identifier ' string. The strings are separated by a colon. Dim newNode As Node Set newNode = Tree.Nodes.Add(ParentNode, tvwChild, _ InterFace.Parent.Parent.ItemID + ":" + _ InterFace.Parent.ElementID + ":" + _ InterFace.InterfaceID, name, Image, Image) Next End Sub
QueryVCDPropertyInterface iterates through all available interfaces of an element. For every interface, it creates a new node. All of these nodes are children of the node which represents the VCDPropertyElement to which these VCDPropertyInterface belong. The Select block determines the appropriate graphical tree element for the node and sets its name, depending on the type of the interface. The name is then assigned to the Text property of the node. The interface path that consists of an itemID, an elementID and an interfaceID is assigned to the key property of the node. The interface node makes up a leaf of the tree.
Now that the tree is built, we want to access the properties. To do this, add a NodeClick event for the tree view and insert the following code:
Private Sub Tree_NodeClick(ByVal Node As MSComctlLib.Node) Dim InterFace As VCDPropertyInterface ' Hide all user controls. RangeFrame.Visible = False SwitchFrame.Visible = False MapStringsFrame.Visible = False ButtonFrame.Visible = False AbsValFrame.Visible = False ' Node is not a leaf If Node.Key = "" Then Exit Sub End If ' The FindInterface operation may fail, so ignore the error and check the return value. ' In this case the returned Interface is Nothing. The interface identifier string ' is stored in the Key property of the passed Node. Set InterFace = ICImagingControl1.VCDPropertyItems.FindInterface(Node.Key) If Not InterFace Is Nothing Then ' Show the user control matching to the type of the selected interface ' and initialize it by passing the interface to the user control's interface ' member. Select Case InterFace.InterfaceID Case VCDInterface_AbsoluteValue: ShowAbsoluteValueControl InterFace Case VCDInterface_MapStrings: ShowComboBoxControl InterFace Case VCDInterface_Range: ShowRangeControl InterFace Case VCDInterface_Switch: ShowSwitchInterface InterFace Case VCDInterface_Button: ShowButtonInterface InterFace End Select End If End Sub
Now it becomes clear, why the keys of the interface nodes store the interface path. If you click an interface node, the appropriate control should appear on the form, so that you can manipulate the setting of the property. To get the correct interface, the method FindInterface is used. FindInterface needs the interface path (or GUID) as a parameter. The key of an interface node represents this interface path (or GUID). The Select block maps the appropriate user control to the desired interface and calls the respective "Show%%" procedure. These procedures set the Visible property of the user control to True, so that it can be used to manipulate the setting of the specified property. The ShowAbsoluteValueControl procedure for example is implemented as follows:
Private Sub ShowAbsoluteValueControl(InterFace As VCDPropertyInterface) AbsValSlider.AssignItf InterFace AbsValFrame.Visible = True AbsValFrame.Caption = InterFace.Parent.Parent.name ' Property item name End Sub
The appropriate procedures for the other user controls are implemented in the same way.
Established in 1990, The Imaging Source is one of the leading manufacturers of industrial cameras, frame grabbers and video converters for production automation, quality assurance, logistics, medicine, science and security.
Our comprehensive range of cameras with USB 3.1, USB 3.0, USB 2.0, GigE interfaces and other innovative machine vision products are renowned for their high quality and ability to meet the performance requirements of demanding applications.