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. [v1.1.12+]: Diese Funktion ist veraltet. Schreiben Sie stattdessen zwei aufeinanderfolgende Kommas, wie z. B. in Obj.Methode(1,,3)

ParamObj := ComObjMissing()

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

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

Um den Code zukunftssicherer zu machen, können Sie 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, der den Typ des Wertes kennzeichnet. Eine Auflistung aller Typennummern finden Sie unter ComObjType().

Wert

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

Flags

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

DispPtr

Roher IDispatch-Pointer.

Flags

 0 

Standardverhalten. AddRef() wird für IUnknown- und IDispatch-Pointer automatisch aufgerufen, daher sollte der Aufrufer ObjRelease() verwenden, um ihre Kopie des Pointers gegebenenfalls freizugeben.

Da das Standardverhalten in einer zukünftigen Version eventuell geändert wird, ist es ratsam, Flags immer auf 1 zu setzen, wenn ein Interface-Pointer gewrappt wird, und ObjAddRef() aufzurufen, falls nötig.

 1  Ergreift Besitz von einem IUnknown-, IDispatch- oder SAFEARRAY-Pointer. AddRef wird nicht aufgerufen. Enthält das Wrapper-Objekt einen SAFEARRAY (außer 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, können leere eckige Klammern [] zum Lesen oder Schreiben des referenzierten Wertes genutzt werden.

Beim Erstellen einer Referenz muss Wert die Speicheradresse einer Variable oder eines Pufferspeichers mit genügend Kapazität sein, um einen Wert bestimmten Typs enthalten zu können. Das folgende Beispiel erstellt eine Variable, die von einer VBScript-Funktion beschrieben werden 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 Beispiel unten initialisiert werden.
MsgBox % vref[]

Allgemeine Bemerkungen

In den aktuellen Versionen wird jeder Funktionsaufruf, der mit "ComObj" beginnt, aber keine der internen COM-Funktionen ist, tatsächlich ComObjActive aufrufen. Zum Beispiel sind ComObjEnwrap(DispPtr) und ComObjActive(DispPtr) beide äquivalent zu ComObject(DispPtr) (standardmäßig mit VarTyp 9). Allerdings wird dieses Verhalten in einer zukünftigen Version nicht mehr verfügbar sein, so dass es am besten ist, nur ComObject() und ComObjActive() zu verwenden, wie auf dieser Seite gezeigt.

Wenn ComObjActive ein aktives Objekt nicht abrufen kann, wird die Funktion je nach aktueller ComObjError()-Einstellung und anderen Faktoren eventuell eine Ausnahme auslösen, das Skript beenden oder eine leere Zeichenkette zurückgeben.

Wenn diese Funktion genutzt wird, um einen IDispatch- oder IUnknown-Interface-Pointer zu wrappen oder abzurufen, wird standardmäßig die Referenzanzahl des COM-Objekts um 1 erhöht. Daher muss der Interface-Pointer, wenn er nicht länger benötigt wird, manuell freigegeben werden. Wenn das Wrapper-Objekt frei wird, wird die darin enthaltene Referenz automatisch freigegeben.

Bekannte Einschränkung: Jedes Mal, wenn ein COM-Objekt gewrappt wird, wird ein neues Wrapper-Objekt erstellt. Bei Vergleichen und Zuweisungen wie if (obj1 == obj2) und array[obj1] := Wert werden beide Wrapper-Objekte nicht als identisch angesehen, obwohl sie das gleiche COM-Objekt enthalten.

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

Beispiele

ComObjUnwrap: Siehe ComObjConnect().

#1

; 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" } ; Näheres zu base finden Sie unter Benutzerdefinierte Objekte.
    ; Erstellt ein Array mit 1 VARIANT.  Durch diese Methode kann der interne 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._))
}