OBJECT statement

Purpose

Communicate with a COM object through the dispatch interface.

Syntax

OBJECT GET interface.member[.member.] [([[paramname =] param1 [, ...]])] TO ResultVar
OBJECT LET interface.member[.member.] [([[paramname =] param1 [, ...]])] = ValueVar
OBJECT SET interface.member[.member.] [([[paramname =] param1 [, ...]])] = ValueVar
OBJECT CALL interface.member[.member.] [([[paramname =] param1 [, ...]])] [TO ResultVar]

OBJECT RAISEEVENT [interface.]member[([[paramname =] param1 [, ...]])]

Remarks

There are five general forms of the OBJECT statement which are used to communicate through a Dispatch interface to an object.

OBJECT GET

Retrieve or read the value of an Interface member Property. This is similar to retrieving the value of a variable.

OBJECT LET

Assign or write a value to an Interface member Property. This is similar to assigning a value to a variable.

OBJECT SET

Assign or write a value to an Interface member Property that contains a reference to an object.  For example, a reference to another Interface.

OBJECT CALL

Call or execute a member Method of an Interface.  This is equivalent to calling a Sub or Function.

OBJECT RAISEEVENT

Call or execute a member Method of a Dispatch event Interface. Because the Dispatch event interface is pre-defined, you are not required to specify the interface name in this form of the statement. However, including it aids in self-documentation of your program. If your program is using a Direct, V-Table event handler you should use the RAISEEVENT statement instead. See the EVENT SOURCE statement for an OBJECT RAISEEVENT example.

All parameters, return values, and assignment values must be in the form of COM-compatible variables.  Literals and expressions are not allowed.  COM-compatible variables include BYTE, WORD, DWORD, INTEGER, LONG, QUAD, SINGLE, DOUBLE, CURRENCY, string, and VARIANT.  You should use caution passing string data since COM Objects require that unicode format be used.  When string data is contained in a VARIANT variable, conversion to/from unicode is automatic, and no intervention is needed from the programmer.  However, if you pass data in a dynamic string variable, you must use the ACODE$() and UCODE$() functions to convert the data to an appropriate format.  For this reason, we recommend that string data be passed using VARIANT variables.

Dispatch OBJECT Method calls may be bound at run-time using late binding, which requires no declaration of Properties and Methods. However, for this very reason, the validity of these references can not be verified by PowerBASIC at the time the program is compiled.

The OBJECT statement can use both positional and named parameters, but you should keep in mind that not all COM Dispatch Servers support named parameters. Positional parameters are universally supported.

A positional parameter is simply a variable containing an appropriate value.  It is identified by its position in the parameter list, just as in a traditional SUB or FUNCTION.  A named parameter consists of a parameter identifier (a name), an equal (=) sign, and a variable containing an appropriate value.  Positional parameters must precede any and all named parameters, but named parameters may be specified in any sequence.

Each time you call a Method or Property using the OBJECT statement, a status code is returned in a hidden parameter to indicate the success or failure of the operation.  You can retrieve information about this status code with the OBJRESULT function, and also by using the IDISPINFO Dispatch Information Object.  If the failure was severe, then a PowerBASIC error 99 (Object Error) is also generated and the ERR system variable is set.  You can find more information about these items by referring to OBJRESULT, IDISPINFO, and ERR.  This information can be very useful for both debugging and handling run-time errors.

Restrictions

All parameters, return values, and assignment values must be in the form of COM-compatible variables.  Use of the wrong member mode (GET/LET/SET/CALL/RAISEEVENT) can sometimes result in unexpected and fatal run-time errors.  So, it's usually prudent to test the result code in OBJRESULT after every OBJECT statement.

See also

ACODE$, DIM, CLASS, CLSID$, EVENT SOURCE, IDISPINFO, GUID$, GUIDTXT$, ID Binding, INTERFACE (Direct), INTERFACE (IDBind), ISINTERFACE, ISNOTHING, ISOBJECT, Just what is COM?, Late Binding, LET (with Objects), METHOD, OBJACTIVE, OBJPTR, OBJRESULT, PROGID$, PROPERTY, UCODE$, What is an object, anyway?, What is DISPATCH?

Example

' Assumes Interface definitions have been

' declared for the Microsoft Agent Control
LOCAL AgentCtrlEx  AS IAgentCtlEx
LOCAL  StartX      AS LONG
LOCAL  StartY      AS LONG
LOCAL  CharW       AS LONG
LOCAL  CharH       AS LONG
LOCAL  Connected   AS LONG
LOCAL  AgentName   AS STRING
LOCAL  AgentFile   AS STRING

' Create a new instance of the COM Object
AgentCtrlEx = NEWCOM $PROGID_Agent2
IF ISFALSE(ISOBJECT(AgentCtrlEx)) THEN EXIT FUNCTION

' Set the connected property
Connected = 1
OBJECT LET AgentCtrlEx.Connected = Connected

' Load the Merlin Agent Character
AgentName = UCODE$("Merlin")
AgentFile = UCODE$("Merlin.acs")
OBJECT CALL AgentCtrlEx.Characters.Load(AgentName, AgentFile)

' Display the Merlin Agent Character on the screen
OBJECT CALL AgentCtrlEx.Characters.Character(AgentName).Show

' Find the center of the screen for the Character Agent
OBJECT GET AgentCtrlEx.Characters.Character(AgentName).Width  TO CharW
OBJECT GET AgentCtrlEx.Characters.Character(AgentName).Height TO CharH
DESKTOP GET CLIENT TO StartX, StartY
StartX = (StartX - CharW)\2
StartY = (StartY - CharH)\2

' Move the Character to the center of the screen
OBJECT CALL AgentCtrlEx.Characters.Character(AgentName).MoveTo(StartX, StartY)
' more code here