Having problems with your account or logging in?
A lot of changes are happening in the community right now. Some may affect you. READ MORE HERE

How can SilkTest access sub-objects of an ActiveX control?

How can SilkTest access sub-objects of an ActiveX control?

ActiveX collection objects are controls that are comprised of sub-objects. Examples of collection objects include treeview, which is a collection of nodes, toolbar, a collection of tool icons and status bar, a collection of static text fields. These collection objects pose challenges for test engineers because the properties and methods of the contained objects can not be directly accessed from 4Test. For example, exposed methods might be available on the treeview to select an item, but specific information about a selected node may only be available on the contained object itself. That information is often important to thoroughly verify application behavior. To call the properties and methods of the contained object, it is necessary to use special access methods found in the 4Test CompoundControl class.

The CompoundControl class is provided in a file called oleclass.inc in the directory where SilkTest is installed. The class contains two sets of function prototypes. The first set includes _GetCollectionProp, _SetCollectionProp and _CallCollectionMethod. These prototypes allow access to methods and properties of the container object. The prototype for _GetCollectionProp is displayed below:

obj ANYTYPE _GetCollectionProp (STRING sCollProp, STRING sPropName)

_GetCollectionProp takes two arguments. The first, sCollProp, is the name of the Collection. The second, sPropName, is the name of the property to get. The "Count" property of a collection could be used to determine the number of contained objects, e.g. the number of tool icons on a toolbar or the number of columns in a table. A call to this method might be written as follows:

iCount = this._GetCollectionProp ("Columns", "Count")

The second set of prototypes including _GetItemProp, _SetItemProp and _CallItemMethod allow access to the properties and methods of the contained objects. The prototype for _GetItemProp is displayed below:

obj ANYTYPE _GetItemProp (STRING sCollProp, INT nIndex, STRING sKey, STRING sPropName)

_GetItemProp takes four arguments. The first parameter sCollProp is the name of the Collection or Interface. Collections can be found in the property section of the class definition for the container object. Collections are usually of type PINTERFACE, which is a pointer to an interface or collection. See the SilkTest documentation for "recording classes" on how to obtain a class definition. An example of a collection property definition is displayed below:

property PINTERFACE ChildNodes alias "$ChildNodes"

The ChildNodes interface provides access to the contained objects. To get a listing and description of available properties and methods, you will need to either consult the documentation for the object or use an Object Browser such as the one within the Visual Basic development environment.
The next two parameters, nIndex and sKey, provide two options for specifying the item in the collection. The first option, nIndex, is the ordinal value of the item in the collection, e.g. the 4th item. sKey is the name of the item, e.g. the string associated with a node in a treeview. If the string, sKey, is empty (""), the numeric value, nIndex, is used. The last parameter, sPropName, is the name of the property to get.

Typically calls to _GetItemProp will be wrapped in a higher level method to provide easy access to a specific property. For example, a method that gets the tool tip associated with a tool in a toolbar or a node in a treeview might be written as follows

[-] STRING GetToolTipText (LISTITEM iListItem)
        [-] if TypeOf (iListItem) == STRING
                 [ ] return (this._GetItemProp ("ChildNodes", 0,iListItem,"ToolTipText"))
        [-] else
                 [ ] return (this._GetItemProp ("ChildNodes", iListItem,"","ToolTipText"))

To call GetToolTipText, the user is required to provide only the contained item as either a string or index. The method then returns the value of the property ToolTipText from the ChildNodes interface.
So far our discussion has been limited to properties. It is also possible to call methods on a contained object in a similar manner. To access methods on a contained object, the CompoundClass prototype _CallItemMethod is used:

obj ANYTYPE _CallItemMethod (STRING sCollProp, INT nIndex, STRING sKey, STRING sMethName, varargs lArgs)

_CallItemMethod is similar to _GetItemProp. The first three parameters are the same. The fourth parameter, sMethoName, is the name of the method to call. The last parameter is a list of the arguments to pass to that method. As with properties the user needs to consult documentation to determine the names of the methods and the number and types of parameters to pass. In the following example, _CallItemMethod is used to get the state of a tool button in a toolbar:

[-] BOOLEAN GetToolState (LISTITEM iListItem)
       [-] if TypeOf (iListItem) == STRING
                 [ ] return (this._ CallItemMethod ("ChildNodes", 0,iListItem,"GetState",{}))
       [-] else
                 [ ] return (this._ CallItemMethod ("ChildNodes", iListItem,""," GetState",{}))

To call GetToolState, the user is required to provide only the contained item as either a string or index. The method then returns a Boolean value which indicates whether the tool is enabled.

Before the access methods can be used in the 4Test class CompoundClass, you must modify your class definition to inherit from it. If the class definition of the object inherits from Control as many ActiveX objects do, the inherited class can simply be changed from Control to CompoundControl as follows;
If the class is defined like this:

winclass StatusBar20WndClass : Control

change its definition like this:

winclass StatusBar20WndClass : CompoundControl

If the ActiveX class already derives from a 4Test class other than Control, it may not be possible to inherit from CompoundControl as previously described. Changing the derived class in this manner would result in loss of inherited class-specific properties and methods. Instead, simply copy the method prototypes from CompoundClass into the class. Usage of the access methods will not be affected in any way.

The ability to access properties and methods from sub-objects will often enable verification of application behavior that would otherwise be possible only with bitmaps. Using the sub-object methods and properties will result in more reliable and maintainable automated tests.

Old KB# 21792


Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Top Contributors
Version history
Revision #:
1 of 1
Last update:
‎2013-02-15 19:24
Updated by:
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.