ComObjConnect() [AHK_L 53+]

Verbindet die Ereignisquellen eines COM-Objekts mit Funktionen, die ein bestimmtes Präfix haben.

ComObjConnect(ComObject , PräfixOderSink)

Parameter

ComObject

Ein Objekt, das Ereignisse auslöst.

Wenn das Objekt das IConnectionPointContainer-Interface nicht unterstützt oder wenn Typinformationen über die Klasse des Objekts nicht abgerufen werden können, wird eine Fehlermeldung angezeigt. Diese Fehlermeldung kann mit ComObjError() oder Try/Catch unterdrückt oder behandelt werden.

[v1.1.22+]: Das IProvideClassInfo-Interface wird verwendet, um Typinformationen über die Klasse des Objekts abzurufen, sofern es vom Objekt unterstützt wird. Andernfalls versucht ComObjConnect, die Typinformationen via IDispatch-Interface des Objekts abzurufen, was unzuverlässig sein kann.

PräfixOderSink

Wenn leer oder weggelassen, wird die Verbindung zum Objekt getrennt, d.h. das Skript erhält keine Benachrichtigungen von seinen Ereignissen mehr. Andernfalls geben Sie eine Zeichenkette an, die dem Ereignisnamen vorangestellt wird, um zu bestimmen, welche Funktion aufgerufen werden soll, wenn ein Ereignis stattfindet, oder in [v1.1.01+] ein Event-Sink-Objekt, das eine Methode für jedes zu behandelnde Ereignis definiert.

Verwendung

Um ComObjConnect effektiv nutzen zu können, müssen Sie zunächst Funktionen in das Skript schreiben, die die entsprechenden Ereignisse behandeln können. Solche Funktionen, auch "Ereignishandler" genannt, haben die folgende Struktur:

PräfixEreignisName([Params..., ComObject])
{
    ... ereignisbehandelnder Code ...
    return RückgabeWert
}

Präfix sollte identisch mit dem PräfixOderSink-Parameter sein, wenn es eine Zeichenkette ist, andernfalls sollte es weggelassen werden. EreignisName sollte mit dem Namen des Ereignisses ersetzt werden, das von der Funktion behandelt werden soll.

Params entspricht den Parametern, die das Ereignis hat. Wenn das Ereignis keine Parameter hat, sollte Params ganz weggelassen werden. ComObject ist optional und kann nur verwendet werden, wenn die korrekte Anzahl von Params definiert ist; es enthält eine Referenz zum originalen Wrapper-Objekt, das an ComObjConnect übergeben wurde. "ComObject" sollte mit einem Namen ersetzt werden, der besser zum Kontext Ihres Skripts passt.

Beachten Sie, dass Ereignishandler Rückgabewerte haben können. Mit ComObject() kann ein COM-spezifischer Wertetyp zurückgegeben werden. Zum Beispiel gibt return ComObject(0,0) eine Variante des Typs VT_EMPTY zurück, was dasselbe ist wie, als würde eine JavaScript-Funktion undefined (oder gar nichts) zurückgeben.

Mit ComObjConnect(MeinObjekt, "Präfix") kann die Ereignisbehandlung aktiviert werden.

Rufen Sie ComObjConnect(MeinObjekt) auf, um die Verbindung zum Objekt zu trennen (Ereignisbehandlungen zu stoppen).

Wenn die Anzahl der Parameter unbekannt ist, kann eine variadische Funktion verwendet werden.

Event-Sink [v1.1.01+]

Wenn PräfixOderSink ein Objekt ist, wird jedes Mal, wenn ein Ereignis ausgelöst wird, die entsprechende Methode dieses Objekts aufgerufen. Obwohl das Objekt dynamisch konstruiert werden kann, ist es für PräfixOderSink typischer, auf eine Klasse oder eine Instanz einer Klasse zu verweisen. In diesem Fall werden die Methoden wie oben definiert, jedoch ohne Präfix.

Wie bei jedem Methodenaufruf enthält der (normalerweise versteckte) this-Parameter der Methode eine Referenz zum Objekt, über das die Methode aufgerufen wurde; also das Event-Sink-Objekt, nicht das COM-Objekt. Dies kann verwendet werden, um den Ereignishandlern Kontext bereitzustellen oder um Werte zwischen ihnen auszutauschen.

Um alle Ereignisse abzufangen, ohne für jedes einzelne eine Methode zu definieren, definieren Sie eine __Call-Metafunktion.

ComObject behält eine Referenz zu PräfixOderSink, d.h. es kann erst gelöscht werden, wenn die Verbindung zum Objekt getrennt wird.

[v1.1.36.02+]: ComObject gibt seine Referenz zu PräfixOderSink automatisch frei, wenn das COM-Objekt die Verbindung freigibt. Das passiert zum Beispiel, wenn der Internet Explorer beendet wird. Wenn das Skript seine eigene Referenz zu PräfixOderSink nicht beibehält, kann es __Delete verwenden, um zu erkennen, wann dies geschieht. Wenn das Objekt von einem Remote-Prozess gehostet wird und der Prozess unerwartet terminiert wird, kann es mehrere Minuten dauern, bis das System die Verbindung freigibt.

Bemerkungen

Das Skript muss eine Referenz zu ComObject beibehalten, andernfalls würde es automatisch freigegeben und die Verbindung zu seinem COM-Objekt trennen, was verhindert, dass weitere Ereignisse erkannt werden. Es gibt keine Standardmethode, um zu erkennen, wann die Verbindung nicht mehr benötigt wird, daher muss das Skript die Verbindung manuell trennen, indem es ComObjConnect aufruft.

Möglicherweise ist die #Persistent-Direktive erforderlich, um das Skript am Laufen zu halten, während es auf Ereignisse wartet.

Bei Misserfolg kann die Funktion eine Ausnahme auslösen, das Skript beenden oder einfach ihren Wert zurückgeben, abhängig von der aktuellen ComObjError()-Einstellung und anderen Faktoren.

ComObjCreate(), ComObjGet(), ComObjActive(), ComObjError(), WScript.ConnectObject (Microsoft Docs)

Beispiele

Startet eine Instanz des Internet Explorers und verbindet Ereignisse mit entsprechenden Skriptfunktionen, die das Präfix "IE_" haben. Details zum hier verwendeten COM-Objekt und zum DocumentComplete-Ereignis finden Sie unter InternetExplorer object (Microsoft Docs).

ie := ComObjCreate("InternetExplorer.Application")

; Verbindet Ereignisse mit entsprechenden Skriptfunktionen, die das Präfix "IE_" haben.
ComObjConnect(ie, "IE_")

ie.Visible := true  ; Funktioniert nicht korrekt unter IE7.
ie.Navigate("https://www.autohotkey.com/")
#Persistent

IE_DocumentComplete(ieEventParam, url, ieFinalParam) {
    global ie
    if (ie != ieEventParam)
        s .= "Erster Parameter ist ein neues Wrapper-Objekt.`n"
    if (ie == ieFinalParam)
        s .= "Letzter Parameter ist das originale Wrapper-Objekt.`n"
    if ((disp1:=ComObjUnwrap(ieEventParam)) == (disp2:=ComObjUnwrap(ieFinalParam)))
        s .= "Beide Wrapper-Objekte verweisen auf dieselbe IDispatch-Instanz.`n"
    ObjRelease(disp1), ObjRelease(disp2)
    MsgBox % s . "Das Laden von " ie.Document.title " @ " url " wurde abgeschlossen."
    ie.Quit()
    ExitApp
}