Late Binding

Start the PowerBASIC COM Browser by executing PBROW.EXE.  The very first time that the PowerBASIC COM Browser is launched, no type-library will be selected.  However, in all subsequent launches, the PowerBASIC COM Browser opens the last type-library that was open when the PowerBASIC COM Browser was last closed.

To open a type-library, we choose File | Open Registered Library from the pull-down menu.  Next, we select "Microsoft Word 8.0 Object Library" from the list of available type-libraries, then choose Open.

The name of the type-library appears in the (read-only) Type-Library text box.  The Program ID also appears in a read-only text box.  The read-only text boxes make it convenient for us to copy the Program ID and paste it into our source code using standard copy/paste techniques.  For example, right-click to bring up the associated context-menu for the text box, or set keyboard focus to the text box and press CTRL+A to select and CTRL+C to copy the ID to the clipboard.

Now we go to the PowerBASIC IDE and open a new document, where we type the following code:

FUNCTION PBMAIN

  DIM oWord AS DISPATCH

  LET oWord = NEW DISPATCH IN "Word.Application.8"

  LET oWord = NOTHING

END FUNCTION

Remembering that we copied the Program ID ("Word.Application.8") to the clipboard just before, we can paste that into the code as we type.  What we have just done is create a program that will start a new instance of Microsoft Word 97.

If we left the NEW clause out of the LET statement, the object variable oWord will refer to the first running instance of Microsoft Word 97 that is found, if it can be found at all.

We can use OBJACTIVE to help determine if an out-of-process COM Object (EXE) is active or not, or we can use the LET statement (without the NEW clause) and rely on run-time error checking to determine success or failure).

We can save, compile, and then run the program as it stands, and it will work.  Of course, it may not appear to work, since Word will probably run fine, but will not be visible to us!  We can check that it is running by looking at the process list using Window's Task Manager utility (Windows NT/2000/XP) or any utility that displays an active process list.

Now we will add code to make Word visible.  We go back to the PowerBASIC COM Browser and see if we can find some Method or Property that would make the application visible.  In the Interfaces list box, we select the Application Interface.

Notice that the Methods/Properties list box will fill with all the available Methods and Properties of the Application Interface.  Also notice that the "?" button above the Syntax text box will be enabled if the COM Interface library has an associated help file.  We can view the help by clicking the ? button, or by choosing Help on the PowerBASIC COM Browser menu, then Help on Library's Topic from the pull-down menu, or simply by pressing the F1 key.

You will note that the Help file for Word 97's Object Library is written for Visual Basic users, so while the syntax is not exactly the same for PowerBASIC, it is very similar.  If we read the information in the Help file on the Application Object, we see that the example shows how to make Word visible.  The key word here is Visible.

Now we examine the Methods/Properties list box, and locate Visible.  There will be two listed.  Examining one then the other, we see that one Visible is a LET and the other is a GET.  That means Visible is an Interface Property.

At this point, we define some terminology just to make sure we are clear:

Interface

Contains Methods and Properties to be used by an application (client/controller) to communicate with a COM Object.

Object

An instance of a COM Object Interface.

Method

An action that an object can perform, similar to a Sub/Function

Property

An attribute of an object.  A Property is similar to a conventional variable.

Properties may be specified as LET or GET (and occasionally as a SET).  LET is used for setting/writing the value of a Property, and GET is used for getting/reading the value held by a Property.  Interface Methods are always accessed by a CALL.

All Interface parameters and return values are passed using Variants.  The syntax shown by the PowerBASIC COM Browser indicates the type of data that is expected to be stored within the Variant.

In the case of unnamed parameters, the syntax does not show a parameter, yet one is expected by the COM Object.  In this case, the parameter type is usually displayed in a comment to the right of the syntax.  The number within the angled brackets "<..>" is the Dispatch ID, which is used by the compiler for early-binding.  Since the number must be accurate, it is a good idea to use the PowerBASIC COM Browser to generate the code.  We'll return to early binding later in this tutorial.

With either Visible Property selected in the Methods/Properties list box, we can press F1 to display the Help for the Visible Property.  This tells us that in order to make Microsoft Word visible, we set the Application.Visible Property to True.

With Variants, we can set the Property to True by assigning it the number 1, or by assigning the literal text "True".  For example:

DIM vBool AS VARIANT

vBool = 1

…or we can use:

vBool = "True"

Both vBool assignments perform the same task when the Property is expecting a Boolean value.  Since dealing with numeric values is almost always faster than dealing with strings, we will give preference to the use of numbers.  Now we edit our code to look like the following:

FUNCTION PBMAIN

  DIM oWord AS DISPATCH

  DIM vBool AS VARIANT

  LET oWord = NEW DISPATCH IN "Word.Application.8"

  vBool = 1

  OBJECT LET oWord.Application.Visible = vBool

  LET oWord = NOTHING

END FUNCTION

We can drop the word "Application" in the "OBJECT LET oWord.Application.Visible = vBool" statement as it is the Object's "global" Interface.  This reduces the OBJECT LET statement so it appears as follows:

OBJECT LET oWord.Visible = vBool

Again, we can learn all this information from the Word 97 Automation Help file (See "Global Object").  Now we will compile and run the modified application code to check that it continues to work fine.

Now we'll return to the macro we mentioned earlier.  If you are unfamiliar with recording macros, please see "macros, creating" or " Recording a macro to generate code" in the Word 97 Help file.  When we recorded our macro to perform the steps we mentioned earlier, this is what Word 97 saved:

Documents.Add Template:="Normal", NewTemplate:=False

Selection.TypeText Text:="PowerBASIC controls Microsoft Word!"

Selection.TypeParagraph

ActiveDocument.SaveAs FileName:="Test.doc", _

  FileFormat:=wdFormatDocument, _

  LockComments:=False, Password:="", _

  AddToRecentFiles:=True, WritePassword :="", _

  ReadOnlyRecommended:=False, _

  EmbedTrueTypeFonts:=False, _

  SaveNativePictureFormat:=False, _

  SaveFormsData:=False, _

  SaveAsAOCELetter:=False

ActiveWindow.Close

 

Now we now know the basics techniques for finding Methods and Properties, we can find each of the above Interfaces and their respective Methods.  Documents and Selection are both interfaces found in the Interfaces list box in the PowerBASIC COM Browser.  ActiveDocument and ActiveWindow are not.

If we select Application in the Interfaces list box, we notice that ActiveDocument and ActiveWindow are both Properties of the Application object.

We select each of these and notice in the Syntax text box that ActiveDocument returns a Document object, and ActiveWindow returns a Window object.  To get further information, we need to select the Document and Window Interface respectively.

Stepping back for a moment, we can see that it is possible for an Interface member to return an object that refers to another Interface in the Object.  This is an important point when using Interfaces - in most cases, one Interface provides the "mechanism" to use the other Interfaces exposed by a COM Object.

Continuing with the example code, we will convert the above Word macro code to PowerBASIC, giving us the following code:

%wdFormatDocument = 0

 

FUNCTION PBMAIN

  DIM oWord AS DISPATCH

  DIM vBool AS VARIANT

  DIM vText AS VARIANT

  DIM vFile AS VARIANT

  DIM vFileFormat AS VARIANT

  LET oWord = NEW DISPATCH IN "Word.Application.8"

  vBool = 1

  OBJECT LET oWord.Visible = vBool

  OBJECT CALL oWord.Documents.Add

  vText = "PowerBASIC controls Microsoft Word!"

  OBJECT CALL oWord.Selection.TypeText(vText)

  OBJECT CALL oWord.Selection.TypeParagraph

  vFile = "Test.doc"

  vFileFormat = %wdFormatDocument

  OBJECT CALL oWord.ActiveDocument.SaveAs(vFile, vFileFormat)

  OBJECT CALL oWord.ActiveWindow.Close

  OBJECT CALL oWord.Quit

  LET oWord = NOTHING

END FUNCTION

Since some of the parameters are optional, we can omit them provided they use the default value.  Default values can be identified through the Object's documentation.

From the code above, you may be wondering where the %wdFormatDocument equate came from.  When examining the Help file for the SaveAs Method in the Document Interface, we will note that the FileFormat parameter can be one of the WdSaveFormat constants.  Switching back to the PowerBASIC COM Browser, we can select WdSaveFormat in the Interfaces list box, and in the Methods/Properties list box, we are presented with a list of constants/values that are available for the FileFormat parameter.

The items in this list are called Enumerations, and these items are prefixed with "[Enum]" in the Interfaces list box to clearly distinguish them from Interfaces.

Select the desired constant in the Methods/Properties list box.  Then, you will be able to copy the value from the Syntax text box.  The PowerBASIC COM Browser helps make this process of "discovery and use" very straightforward.

Notice that we also added the Quit call at the end of the above code.  This terminates Microsoft Word.  At this point, we can compile and run the above code.  Microsoft Word will briefly flash up on the screen and then disappear.

To verify that the program code worked as intended, we can open Microsoft Word and then open the TEST.DOC document and check that Word did exactly what it was instructed to do - fill in the text "PowerBASIC controls Microsoft Word!".

 

See Also

COM Programming Introduction

The PowerBASIC COM Browser

Early-binding and Late-binding

Early Binding Tutorial

How does the LET statement work?