OLE / COM

 

The ability to control and assist the movement of data between applications is one of the key strengths of WIL. There many ways to share data between applications: using the Clipboard, dynamic data exchange (DDE), Control Manager Functions, SendKey functions and COM.

Now, with support for COM, you can do much more than share data. From within your WIL script, you can access and manipulate COM objects that are supplied by other applications. With COM Automation, you can use WIL to produce custom solutions that utilize data and features from applications that support COM Automation.

 

What Is COM Automation?

COM Automation is an industry standard that applications use to expose their COM objects to development tools, macro languages, and container applications that support COM Automation. For example, a spreadsheet application may expose a worksheet, chart, cell, or range of cells - all as different types of objects. A word processor might expose objects such as applications, paragraphs, sentences, bookmarks, or selections. When an application supports COM Automation, the objects it exposes can be accessed by WIL. You use WIL scripts to manipulate these objects by invoking methods (subroutines) on the objects, or by getting and setting the objects' properties (values).

 

Accessing COM Objects

You can manipulate other applications' COM objects directly by first opening the object with the ObjectGet and ObjectCreate functions.

ObjectCreate vs. ObjectGet: What's the Difference?

Besides minor differences in the syntax, the ObjectCreate and ObjectGet functions are used in different contexts. The differences can be summarized as follows:

 

The ObjectCreate function is used to open the object. This function accepts a string (ProgId) that indicates the application name and the type of object you want to create. Use the following syntax to specify an object to create:

Application.ObjectType

 

For example, let's say there is a orgchart application named ORGCHART.EXE that supports a single object: an orgchart. Furthermore, the OrgChart object supports two sub-objects: a box and a line. The object might be defined as:

OrgChart.Chart

 

Once you know the type of object you want to create, you use the ObjectCreate function to create the object. Capture the value returned by the ObjectCreate function to a variable. Here's an example:

objchart = ObjectCreate("OrgChart.Chart")

 

Once you have the primary object in hand - in the 'objchart' variable in this case, you can create the sub-objects and assign them to their own variables.

objtopbox = objchart.NewBox

objbottombox = objchart.NewBox

objline = objchart.NewLine

 

When this code executes, the application providing the object is started (if it is not already running) and an object is created. The object belongs to the application that created it. This object can be referenced using the variable you placed the return value of the ObjectCreate function. For example, after creating the object, you could write code to open sub-objects, change the background color, set a default font, set a title, and save the object to a file:

objchart.Color = "White"

objchart.FontName = "Arial"

objchart.FontSize = 12

objchart.Title = "Deana’s Org Chart"

objtopbox.Position(2,2)

objtopbox.Text = "The Boss"

objbottombox.Position(2,8)

objbottombox.Text = "Deana"

objline.Begin(2,2)

objline.End(2,8)

objchart.SaveAs("C:\ORGCHART\DEANA.ORG")

 

When creating an object, some applications require that the application providing the object is either active or on the system's path.

When you are through with an object, set the object equal to a null string ("") or to 0 (zero) to tell the WIL processor that you are done with the object.

objline = ""

objtopbox = ""

objbottombox = ""

objchart = ""

 

To get a list of objects that an application supports, you must consult that application's documentation. It may also help to poke around in the Windows registry. For example check out the HKEY_CLASSES_ROOT key. Be aware, though, that intentional, unintentional, or accidental changes to the registry may completely destroy a Windows installation and require a complete re-installation of ALL your software to recover.

 

Accessing an Object's Properties

To assign a value to a property of an object, put the object variable and property name on the left side of an equation and the desired property setting on the right side. For example:

objchart.Title = "Deana’s Org Chart"

 

You can also retrieve property values from an object:

TheTitle = objchart.Title

 

Performing Object Methods

In addition to getting and setting properties, you can manipulate an object using the methods it supports. Some methods may return a value. Methods that do not return a value, return 0.

objchart.Position(2,2)

objline.End(2,8)

objchart.SaveAs("C:\ORGCHART\DEANA.ORG")

rslt = objchart.Print( )

If rslt == @FALSE

   Message("Error", "Print failed")

endif

 

Dealing with Sub-Objects

Some objects contain sub-objects. For example, a box is a sub-object of an orgchart object. Note: You can include multiple objects, properties and methods on the same line of code. For example:

objtopbox = objchart.NewBox

Or

objsubbox = objchart.NewBox.SubBox

 

Collections

A collection represents a set of objects. There are several different ways you can loop through the elements of a collection. However, the recommended method is to use the ForEach...Next loop. In this structure, WinBatch repeats a block of statements for each object in a collection. The following example displays the name of each worksheet in the WorkSheets collection.

ForEach objWorkSheet In ObjExcel.WorkSheets

   Message("WorkSheet Name", objWorkSheet.Name)

Next

 

Another way to loop through the elements of a collection is to use the Item property or method and pass the name or index number of the member as the index argument. For example, in Excel, the following expression returns a reference to an open workbook by passing its name "Sales.xls" to the Item property and then invokes the Close method to close it:

objworkbooks.Item("Sales.xls").Close

 

The Item property or method is the default for most collections.

objworkbooks.Item("Sales.xls")

 

To reference items in a collection by using an index number, simply pass the number of the item to the Item property or method of the collection. For example, if Sales.xls is the second workbook in the Workbooks collection, the following expression will return a reference to it:

objWorkbooks.Item(2)

 

Closing an Object

All COM Automation objects support some method that closes the object and the application that created it. Since COM objects can use a significant amount of memory, it is a good idea to explicitly close an object when you no longer need it. To close an object. use the appropriate method (most objects support the Close method or the Quit method). For example:

;Closes the object.

objchart.Close

;Closes the application that created the object.

objchart.Quit

 

When WIL processing for an object is complete, set the object variable to a null string or 0 (zero) to free WIL processor memory.

objchart = ""

or

objchart = 0

 

Omitted Optional Positional Parameters

COM functions support 'omitted optional positional parameters', using commas as placeholders. 'Required parameters' are those that must always be specified. 'Optional parameters' are those that can be skipped using a comma as a placeholder (when using positional parameters), or simply omitted (when using named parameters).

For example:

objapp.Display("Hello", 100, 100, , 1)

 

Named Parameters

COM functions support 'named parameters'. The syntax structure is:

Object.Method(p1, p2, :: n3 = v3, n4 = v4)

 

Positional Parameters

Positional parameters (shown above as p1 and p2), if any, come first, followed by a double colon ("::"), and then any named parameters (n3 and n4). Each named parameter is followed by an equals sign ("=") and then the value for the parameter (v3 and v4). Whitespace is ignored. Here are some examples:

; 2 positional parameters

objapp.InputBox("My Prompt", "My Title")

 

; 2 positional parameters and 2 named parameters

objapp.InputBox("My Prompt", "My Title", :: Left = 40, Top = 300)

 

; no positional parameters and 2 named parameters

;(note the leading colon)

objapp.InputBox(:: Prompt = "My Prompt", Title = "My Title")

 

COM Types

COM functions allow you to specify the variant type for parameters. Normally, when you specify an value as a parameter to a COM function, WIL passes it as a type VT_I4 (4-byte integer value). If the COM application was expecting the parameter to be a different type of value, in most cases it will automatically convert it to the desired type. However, there are some COM applications which don't do this, and return an error instead.

In such cases, you can first specify the type using the function ObjectType. Or you can specify the type, using the following syntax:

Object.Method(p1, type:p2 :: name = value, type:name = value)

 

The parameter type (shown as 'type') is followed by a single colon (":"), and then the parameter itself. This can be done for both positional parameters and named parameters. White space is ignored, and the type names are not case-sensitive.

Data types which may be specified:

Variant Type

Meaning

NULL

This is like a pointer to NULL.

I1

1-byte signed integer.

I2

Two bytes representing a 2-byte signed integer value.

I4

4-byte signed integer value.

I8

8-byte signed integer value.

R4

32-bit IEEE floating point value.

R8

64-bit IEEE floating point value.

DECIMAL

A decimal value, specified as a string in the form "#DECIMAL:value".

UI1

1-byte unsigned integer.

UI2

2-byte unsigned integer.

UI4

4-byte unsigned integer.

UI8

8-byte unsigned integer.

CY

A currency value, specified as a string in the form "#CURRENCY:value".

DATE

A date/time value, specified as a string in Ymd or YmdHms format

BSTR

A string.

BOOL

A Boolean (True/False) value

ARRAY

If the type indicator is combined with ARRAY by an OR operator, the value is a pointer to a SAFEARRAY. ARRAY can use the OR with the following data types: I1, UI1, I2, UI2, I4, UI4, INT, UINT, R4, R8, BOOL, DECIMAL, ERROR, CY, DATE, and BSTR. ARRAY cannot use OR with VECTOR.

DISPATCH

A pointer to an object was specified. This object is known only to implement IDispatch.

 

 

Note: The default type for integer values is "I4" (VT_I4).

Here are some examples:

; this function requires a parameter of type VT_I2

objapp.CreateImageViewerObject(I2:1)

 

; this function requires a (named) parameter of type VT_DATE

objapp.CreateLog("access.log", :: DATE:startdate="97:11:01")

 

Byte Arrays

COM methods or properties that return byte arrays (variant type = VT_I1 | VT_ARRAY), by default will return as WIL array.

 

COM 2.0 Limitations in WIL

Some COM objects support features that can't be accessed using WIL. This section discusses known limitations.

COM method and property names are limited to 256 characters in length.