Calling COM functions


Methods, property-get functions and property-put functions are called using syntax:


[... = ]ip.method[(parameters)]
[... = ][(parameters)][(parameters)] = value


Here ip is interface pointer variable; method and property are names of functions. Parameters often have BSTR or VARIANT type, but you can pass values of QM intrinsic types (str, etc) instead. QM converts them automatically.


Most COM functions actually return error code, which is 0 on success, negative on error, positive on partial success or if function returns some information. In C++ it is defined as integer of type HRESULT (int in QM). You don't use it when calling functions. Instead, as return value is used the last parameter if in type library it is marked as return value. If function returns negative HRESULT, QM generates error, which can be handled (err). This behavior is only if function's return value is declared as HRESULT (near all functions are declared in this way). QM stores last called COM function's return value in special variable _hresult.

Multiple calls in single statement

A single statement can contain more than one function call. If a function returns interface pointer, you can immediately call a function on that interface pointer. For example, statement:


Excel.Worksheet xlSheet=+xlApp.Workbooks.Add(xlWBATWorksheet).ActiveSheet


does the same job as the following three statements:


Excel.Workbooks xlBooks=xlApp.Workbooks
Excel.Workbook xlBook=xlBooks.Add(xlWBATWorksheet)
Excel.Worksheet xlSheet=+xlBook.ActiveSheet


QM 2.3.0: This also can be used with interfaces declared using interface.

Arguments passed by reference

For "by reference" parameters (& in QM status bar), you must pass variable of that type, or address of variable of that type. You cannot pass simple number or string as you could do in Visual Basic. For example, VB statement


doc = Documents.Add("file")


would be the same in QM, but only if argument is passed by value (e.g., declared as VARIANT'filename). If argument is passed by reference (e.g., declared as VARIANT&filename), it should be


VARIANT v="file"; doc = docs.Add(v)
VARIANT v="file"; doc = docs.Add(&v)

Default member

QM does not support default members. For example, Visual Basic statement


doc = docs(1) ;;get item #1 from collection


in QM could be


doc = docs.Item(1)


In the popup list of functions default member is blue.

Optional parameters

QM partially supports optional parameters.


In QM status bar, optional parameters are displayed with [ ], like [param]. Optional parameters that have a default value are displayed like [param=1].


Optional parameters of VARIANT type can be omitted. Or use @ instead. If there is a default value, use the value.


In the example, we call function Func. Assume it has 3 parameters, all optional. We pass x for parameter 2.


ip.Func(@ x)

Variable number of arguments

Some COM functions support variable number of arguments. For such functions QM displays "vararg" in status bar.


Store arguments into an ARRAY(VARIANT) variable and pass it as the last argument. Example:


Assume that QM status bar shows this: Func(BSTR's ARRAY(VARIANT)*a) . vararg


ARRAY(VARIANT) a.create(2)
a[0] = 1; a[1] = "string2"
ip.Func("string1" &a)


When calling through IDispatch::Invoke, simply pass the arguments. IDispatch::Invoke is used when the variable is of type IDispatch, or #opt dispatch 1 is set, or the interface does not support vtbl binding. Example:


ip.Func("string1" 1 "string2")

I don't have type library, and don't want to declare interface

You can also call functions of undeclared interfaces. Interface pointer variable must be of IDispatch type. Example:


IDispatch app._create("Word.Application")
app.Visible = -1


Argument types should match the expected types. QM does implicit conversions only where it is obvious, such as str to BSTR. The type of the return value is always VARIANT.


QM cannot show type info (popup list of functions, and in status bar) for undeclared interfaces.


You can also use VBScript or JScript code in QM. Example:


lpstr code=
 Set app=CreateObject("Word.Application")
VbsExec code


Or, parts of code that manipulates single object can be in VBScript, and other parts in QM. Functions VbsFuns and VbsEval can be used to exchange values between VBScript and QM.



See other topics and COM samples in the forum.