Methods and Properties

A Dispatch Interface consists of a group of members deemed Methods and Properties.  A Method is very similar to a normal function - it may take parameters and may return a result.  A Property is more like a variable - it can hold a value or state.

A single Dispatch Interface can contain one or possibly hundreds of individual members.

PowerBASIC allows full access to Dispatch Interface members (Methods or Properties); however it is not possible to access a Property value directly.  Rather, reading or writing a Property value has to be performed thorough the appropriate Interface Property member.  This is similar to making a normal function call.

While this seems unusual compared with normal BASIC programming, it is actually an important principle of COM - only the Object itself can manipulate the data held within the Object's internal variables.  This guarantees that the Object itself is wholly responsible for the movement of data in and out of the Object, providing an additional layer of security.

In addition to using the Property functions provided by the Interface, all return results and parameters passed from/to a Property (and a Method) must be performed using VARIANT variables.

Since Variants can be used to hold any type of data, from bytes to string arrays, they are the most convenient way to pass data between an application and a COM Object.  Additionally, COM uses Unicode format for all string-type data, but PowerBASIC automatically handles the translation between ANSI and Unicode for us.

With these rules in mind, let's use some real code to demonstrate accessing Interface Methods and Properties exposed by Microsoft Word™.

The following code performs a number of steps.  It starts off by attempting to reference an existing instance to Microsoft Word™ or starting a new instance if there is no existing one.  Next, it counts the number of documents open in Word, adds a document, places some text in the document, saves the document, and finally, closes the document and Word itself.

The code uses early-binding, but the actual INTERFACE definitions are not shown due to their relatively large size.  The #INCLUDE file used to compile this code was generated directly by the PowerBASIC COM Browser and saved as a .INC file.  The code also uses the optional LET statement for the purposes of clarity, but this is not compulsory.

#COMPILE EXE

#INCLUDE "oword.inc"

 

FUNCTION PBMAIN()

  DIM oWordApp  AS WordApplication ' Application Interface

  DIM oWordDoc  AS WordDocument    ' Document Interface

  DIM oWordSel  AS WordSelection   ' Selection

 

  DIM vBool     AS VARIANT

  DIM vText     AS VARIANT

  DIM vFile     AS VARIANT

  DIM vFileFmt  AS VARIANT

  DIM vVnt      AS VARIANT

  DIM sResult   AS STRING

 

  ' Open an instance of MSWORD

  LET oWordApp = WordApplication IN "Word.Application"

  IF ISFALSE ISOBJECT(oWordApp) THEN _

    LET oWordApp = NEW WordApplication IN "Word.Application"

 

  ' Could MSWORD be opened? If not, terminate this app

  IF ISFALSE ISOBJECT(oWordApp) THEN EXIT FUNCTION

 

  ' Make MSWORD visible

  LET vBool = 1

  OBJECT LET oWordApp.Visible = vBool

 

  ' Get the current document count from the "documents collection"

  LET vVnt = 0

  OBJECT GET oWordApp.Documents.Count TO vVnt

  sResult = "MSWORD has " + FORMAT$(VARIANT#(vVnt)) + _

      " Files loaded!"

 

  ' Add a document to the "documents collection", and obtain a reference

  ' to the document Interface for the new document

  LET vVnt = 0

  OBJECT CALL oWordApp.Documents.Add TO vVnt

  LET oWordDoc = vVnt

 

  ' Get the current document count from the "documents collection"

  ' This should be one value higher than before

  LET vVnt = 0

  OBJECT GET oWordApp.Documents.Count TO vVnt

  sResult = "MSWORD has " + FORMAT$(VARIANT#(vVnt)) + _

      " Files loaded!"

 

  ' Get the Interface to the correct selection of the document

  OBJECT GET oWordApp.Selection TO vVnt

  LET oWordSel = vVnt

 

  ' Enter some text into the document at the selection position

  LET vText = "PowerBASIC controls Microsoft Word!"

  OBJECT CALL oWordSel.TypeText(vText)

 

  ' Set a paragraph marker (end of paragraph)

  OBJECT CALL oWordSel.TypeParagraph

 

  ' Another paragraph

  LET vText = "COM client controls a COM server!"

  OBJECT CALL oWordSel.TypeText(vText)

  OBJECT CALL oWordSel.TypeParagraph

 

  #IF %DEF(%PB_CC32)

    PRINT "Press a key to continue the demo"

    WAITKEY$

  #ELSE

    MSGBOX "Click to continue the demo", &H00002000& ' = %MB_TASKMODAL

  #ENDIF

 

  ' Save the new document to disk

  LET vFile    = "Test.doc"

  LET vFileFmt = %wdFormatDocument

  OBJECT CALL oWordDoc.SaveAs(vFile, vFileFmt)

 

  ' Close the current document and then close MSWORD completely

  OBJECT CALL oWordApp.ActiveWindow.Close

  OBJECT CALL oWordApp.Quit

 

  ' Close all of the Interfaces

  LET oWordSel  = NOTHING

  LET oWordDoc  = NOTHING

  LET oWordApp  = NOTHING

END FUNCTION

As can be seen, this code performs minimal error testing or validation of the Interfaces returned.  However, it still clearly shows some important concepts.  For example, it clearly shows how the return result from several different Properties can return Interface references in the Variant TO variables.  In these cases, the code assigns the references to object variables so that the returned Interfaces can be used with further OBJECT statements. 

 

See Also

COM Programming Introduction

The PowerBASIC COM Browser

Parameters