Automation

Introduction

Automation is a process by which one program may open, control and close a second through the use of a dedicated COM library. The purpose of such an action is to use the resources of that second program to execute a task and, if necessary, return one or more values to the calling program.

For the purpose of this article, we shall automate Internet Explorer as it is, currently, a program available to all Windows users. Other applications that can be automated include Word, Excel and Powerpoint and virtually any other program with an associated COM library.

Creating and Using Automated Objects

The principle of Automation is relatively simple.

To facilitate Automation you can either create a COM object using CreateObject, which causes an occurence of the called program to open in a new process, or use GetObject to try and take control of an occurence of the program which is already running.

Once you have access to the second program, you may then use its predefined Properties and Methods to navigate through the program, read, edit and extract content and perform whatever tasks specific to that application that the Methods allow.

Finally, once you have no further use for the called program, you can force it to exit (or leave it running if you wish) and then destroy the COM object.

Below is a very quick example of this process in practice. Firstly, a control window is drawn which allows for remote exiting of Internet Explorer; then the COM Object itself is created and used to start an occurence of Internet Explorer which, in turn, is used to navigate to Google to search for references to 'GFABasic'. Internet Explorer can be closed normally or remotely but the running program will not cease until the control window is closed.

// Draw Control Window

OpenW 1, 10, 10, 100, 100

Ocx Command cmd = "Close IE", 10, 10, (90 - (Screen.cxFrame * 2)), (90 - Screen.cyCaption - (2 * Screen.cyFrame))

// Create the COM Object

Global ie As Object

Set ie = CreateObject("InternetExplorer.Application")

If Not IsNothing(ie)                                            // If COM Object is created

ie.Visible = True                                             // Show Internet Explorer

~ie.navigate("http://www.google.com/#hl=en&q=" & "GFABasic"// Navigate to Google and Search for 'GFABasic'

While ie.busy : DoEvents : Wend                               // Wait for the page to finish loading

While Not IsNothing(ie) : Sleep : Wend                        // DoEvents until Internet Explorer or Control Window is closed

EndIf

CloseW 1                                                        // Close Control Window

 

Sub cmd_Click

If Not IsNothing(ie)

// Try and close Internet Explorer

Try

ie.quit

Catch

// Internet Explorer has been closed by user

EndCatch

Set ie = Nothing

EndIf

EndSub

 

Sub Win_1_Close(Cancel?)

// Make sure Internet Explorer is closed and ie is Nothing

cmd_Click

EndSub

It is beyond the scope of this article to list all the properties and methods that can be used but the following links may prove useful:

_DispID and .{}

GFABasic has two functions which can be used when determining and returning values of Automation object properties: _DispID and .{}. These are discussed in detail on Sjouke Hamstra's blog but a quick precis of the details are as follows.

Generally, most properties related to a COM object can be accessed using the property's name: hence, to check that Internet Explorer is visible, ie.Visible is queried and returns either a True or False value accordingly.

Sometimes, a COM property may not be available to a program as a named property (usually because it is new): this is where _DispID(Object, PropertyName) and Object.{IDispatchID} come in useful. _DispID queries the Object for the PropertyName which returns the IDispatchID (if the property exists) which can then be used by .{} to retrieve the relevant value. Hence, for the Internet Explorer Visible property, the following procedure could be followed:

Debug.Show

Dim ie As Object

Set ie = CreateObject("InternetExplorer.Application")

Trace ie.visible

Local idisp As Int32 = _DispID(ie, "Visible")

Trace idisp

Trace ie.{idisp}

~ie.quit

Set ie = Nothing

Unfortunately, at the time of writing, the .{} function can not be used to set the property due to a compiler error; when it is used in the logical fashion ie.{402} = True, an 'Internal: Set Prop value' error message is displayed.

{Created by Sjouke Hamstra; Last updated: 08/03/2018 by James Gaite}