ComObjActive() [AHK_L 53+]

Ermittelt ein laufendes Objekt, das mit OLE registriert wurde.

ComObject := ComObjActive(CLSID)

Erstellt ein Objekt, das in typisierter Form als Parameter oder Rückgabewert übergeben werden kann.

ParamObj := ComObject(VarTyp, Wert [, Flags])

VERALTET:

Die unten gezeigten Verwendungen sind veraltet und werden in einer zukünftigen Version geändert oder nicht mehr zur Verfügung stehen.

Erstellt ein Objekt, das stellvertretend für den Standardwert eines optionalen Parameters verwendet werden kann, wenn eine Methode eines COM-Objekts aufgerufen wird. Veraltet seit v1.1.12: Schreibe stattdessen zwei aufeinanderfolgende Kommas, wie z. B. in Obj.Methode(1,,3).

ParamObj := ComObjMissing()

Wrappt oder entwrappt einen unbearbeiteten IDispatch-Pointer in ein brauchbares Objekt und ruft automatisch AddRef auf.

ComObject := ComObjEnwrap(DispPtr)
DispPtr := ComObjUnwrap(ComObject)

Für einen zukunftsicheren Code solltest du stattdessen Folgendes verwenden:

ComObject := ComObject(9, DispPtr, 1), ObjAddRef(DispPtr)
DispPtr := ComObjValue(ComObject), ObjAddRef(DispPtr)

Parameter

CLSID

CLSID oder eine visuell lesbare ProgID des COM-Objekts.

ComObject

COM-Objekt, das mit der Objekt-Syntax verwendbar ist.

VarTyp

Ein Integer-Wert, der den Typ des Wertes kennzeichnet. Siehe ComObjType() für eine Liste von Typen.

Wert

Der Wert, der gewrappt werden soll. Zurzeit werden nur Integer- oder Pointer-Werte unterstützt.

Flags

Flags haben Einfluss auf das Verhalten dieser Funktion und des Wrapper-Objekts (siehe unten).

DispPtr

Unbearbeiteter IDispatch-Pointer.

Flags

 0 

Standardverhalten. AddRef wird bei einem IUnknown- und IDispatch-Pointer automatisch aufgerufen, daher sollte der Aufrufer ObjRelease verwenden, um deren Kopie des Pointers bei Bedarf wieder freizugeben.

Da das Standardverhalten in einer zukünftigen Version geändert werden könnte, empfiehlt es sich, Flags immer auf 1 zu setzen, wenn ein Interface-Pointer gewrappt wird, und bei Bedarf ObjAddRef() aufzurufen.

 1  Ergreift Besitz von einem IUnknown-, IDispatch- oder SAFEARRAY-Pointer. AddRef wird nicht aufgerufen. Enthält das Wrapper-Objekt einen SAFEARRAY (ohne VT_BYREF), wird beim Freigeben des Wrapper-Objekts SafeArrayDestroy automatisch aufgerufen.

ByRef [v1.1.17+]

Wenn der VarTyp eines Wrapper-Objekts den VT_BYREF-Flag (0x4000) enthält, kann mit leeren Klammern [] der verwiesene Wert gelesen oder geschrieben werden.

Beim Erstellen eines Verweises muss Wert die Speicheradresse einer Variable oder Puffer mit ausreichender Kapazität sein, um einen Wert des angegebenen Typs enthalten zu können. Zum Beispiel könnte man wie folgt eine Variable erstellen, in der eine VBScript-Funktion etwas schreiben kann:

VarSetCapacity(var, 24, 0)
vref := ComObject(0x400C, &var)  ; 0x400C ist eine Kombination von VT_BYREF und VT_VARIANT.

vref[] := "Eingabewert"
sc.Run("Beispiel", vref)  ; sc sollte wie im unteren Beispiel initialisiert werden.
MsgBox % vref[]

Allgemeine Bemerkungen

In den aktuellen Versionen wird jeder Funktionsaufruf, der mit "ComObj" beginnt und nicht mit den anderen COM-Funktionen übereinstimmt, eigentlich ComObjActive aufrufen. Zum Beispiel sind ComObjEnwrap(DispPtr) und ComObjActive(DispPtr) das gleiche wie ComObject(DispPtr) (VarType 9 ist inbegriffen). Allerdings wird dieses Verhalten in einer zukünftigen Version nicht mehr zur Verfügung stehen, daher ist es am besten, nur ComObject() und ComObjActive() zu verwenden, wie unten gezeigt.

Wenn mit dieser Funktion ein IDispatch- oder IUnknown-Interface-Pointer gewrappt oder abgerufen wurde, erhöht sich standardmäßig die Referenzzählung des COM-Objekts. Daher muss der Interface-Pointer manuell freigegeben werden, wenn er nicht länger benötigt wird. Beim Freigeben des Wrapper-Objekts wird auch dessen Verweis automatisch freigegeben.

Bekannte Einschränkung: Jedes Mal, wenn ein COM-Objekt gewrappt wurde, wird ein neues Wrapper-Objekt erstellt. Vergleiche und Zuweisungen wie obj1 == obj2 und array[obj1] := Wert behandeln die zwei Wrapper-Objekte getrennt voneinander, selbst wenn sie das gleiche COM-Objekt enthalten.

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

Beispiele

ComObjUnwrap: Siehe ComObjConnect.

; Einleitung - ScriptControl benötigt eine 32-Bit-Version von AutoHotkey.
code =
(
Sub Beispiel(Var)
    MsgBox Var
    Var = "Ausgabewert!"
End Sub
)
sc := ComObjCreate("ScriptControl"), sc.Language := "VBScript", sc.AddCode(code)


; Beispiel: VARIANT-ByRef an eine COM-Funktion übergeben.
var := ComVar()
var[] := "Eingabewert"
sc.Run("Beispiel", var.ref)
MsgBox % var[]


; ComVar: Erstellt ein Objekt, mit dem ein Wert via ByRef übergeben werden kann.
;   ComVar[] bekommt den Wert.
;   ComVar[] := Val setzt den Wert.
;   ComVar.ref bekommt ein ByRef-Objekt, das eine COM-Funktion nutzen kann.
ComVar(Type=0xC)
{
    static base := { __Get: "ComVarGet", __Set: "ComVarSet", __Delete: "ComVarDel" }
    ; Erstellt ein Array mit 1 VARIANT.  Durch diese Methode kann der Built-In-Code sich um
    ; alle Umwandlungen zwischen VARIANT und AutoHotkey's interne Typen kümmern.
    arr := ComObjArray(Type, 1)
    ; Sperrt das Array und bekommt einen Pointer, der auf das VARIANT verweist.
    DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data)
    ; Speichert das Array und ein Objekt, mit dem das VARIANT-ByRef übergeben werden kann.
    return { ref: ComObject(0x4000|Type, arr_data), _: arr, base: base }
}

ComVarGet(cv, p*) { ; Wird aufgerufen, wenn das Skript auf ein unbekanntes Feld zugreift.
    if p.MaxIndex() = "" ; Keine Namen/Parameter, also cv[]
        return cv._[0]
}

ComVarSet(cv, v, p*) { ; Wird aufgerufen, wenn das Skript ein unbekanntes Feld setzt.
    if p.MaxIndex() = "" ; Keine Namen/Parameter, also cv[]:=v
        return cv._[0] := v
}

ComVarDel(cv) { ; Wird aufgerufen, wenn das Objekt freigegeben wird.
    ; Notwendig, damit das interne Array freigegeben werden kann.
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(cv._))
}