ComObject

Wraps a value, SafeArray or COM object for use by the script or for passing to a COM method.

ComObject := ComObject(VarType, Value , Flags)

Advanced: Wraps or unwraps a raw IDispatch pointer for use by the script.

ComObject := ComObject(DispPtr)

Parameters

VarType

An integer indicating the type of value. See ComObjType for a list of types.

Value

The value to wrap. Currently only integer and pointer values are supported.

Flags

Flags affecting the behaviour of the wrapper object; see ComObjFlags for details.

DispPtr

Raw IDispatch pointer.

Return Value

Returns a wrapper object containing a variant type and value or pointer.

This object has two uses:

  1. Some COM methods may require specific types of values which have no direct equivalent within AutoHotkey. This function allows the type of a value to be specified when passing it to a COM method. For example, ComObject(0xB, -1) creates an object which represents the COM boolean value true.
  2. Wrapping a COM object or SafeArray enables the script to interact with it more naturally, using object syntax. However, the majority of scripts do not need to do this manually since a wrapper object is created automatically by ComObjCreate, ComObjArray and any COM methods which returns an object.

ByRef

If a wrapper object's VarType includes the VT_BYREF (0x4000) flag, empty brackets [] can be used to read or write the referenced value.

When creating a reference, Value must be the memory address of a variable or buffer with sufficient capacity to store a value of the given type. For example, the following can be used to create a variable which a VBScript function can write into:

VarSetCapacity(var, 24, 0)
vref := ComObject(0x400C, &var)  ; 0x400C is a combination of VT_BYREF and VT_VARIANT.

vref[] := "in value"
sc.Run("Example", vref)  ; sc should be initialized as in the example below.
MsgBox % vref[]

General Remarks

When this function is used to wrap an IDispatch or IUnknown interface pointer, the wrapper object assumes responsibility for automatically releasing the pointer when appropriate. If VarType was omitted, the object is queried for its IDispatch interface; if one is returned, DispPtr is immediately released. Therefore, if the script intends to use the pointer after calling this function, it must call ObjAddRef(DispPtr) first.

The VarType of a wrapper object can be retrieved using ComObjType.

The Value of a wrapper object can be retrieved using ComObjValue.

Known limitation: Each time a COM object is wrapped, a new wrapper object is created. Comparisons and assignments such as obj1 == obj2 and array[obj1] := value treat the two wrapper objects as unique, even though they contain the same COM object.

ComObjCreate, ComObjGet, ComObjConnect, ComObjError, ComObjFlags, ObjAddRef/ObjRelease, ComObjQuery, GetActiveObject (MSDN)

Examples

; Preamble - ScriptControl requires a 32-bit version of AutoHotkey.
code := "
(
Sub Example(Var)
    MsgBox Var
    Var = "out value!"
End Sub
)"
sc := ComObjCreate("ScriptControl"), sc.Language := "VBScript", sc.AddCode(code)


; Example: Pass a VARIANT ByRef to a COM function.
var := ComVar()
var[] := "in value"
sc.Run("Example", var.ref)
MsgBox % var[]

; ComVar: Creates an object which can be used to pass a value ByRef.
;   ComVar[] retrieves the value.
;   ComVar[] := Val sets the value.
;   ComVar.ref retrieves a ByRef object for passing to a COM function.
ComVar(Type:=0xC)
{
    static base := { __Get: "ComVarGet", __Set: "ComVarSet", __Delete: "ComVarDel" }
    ; Create an array of 1 VARIANT.  This method allows built-in code to take
    ; care of all conversions between VARIANT and AutoHotkey internal types.
    arr := ComObjArray(Type, 1)
    ; Lock the array and retrieve a pointer to the VARIANT.
    DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data)
    ; Store the array and an object which can be used to pass the VARIANT ByRef.
    return { ref: ComObject(0x4000|Type, arr_data), _: arr, base: base }
}
ComVarGet(cv, p*) { ; Called when script accesses an unknown field.
    if !p.Length()  ; No name/parameters, i.e. cv[]
        return cv._[0]
}
ComVarSet(cv, v, p*) { ; Called when script sets an unknown field.
    if !p.Length()  ; No name/parameters, i.e. cv[]:=v
        return cv._[0] := v
}
ComVarDel(cv) { ; Called when the object is being freed.
    ; This must be done to allow the internal array to be freed.
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(cv._))
}