ComObjConnect

将 COM 对象的事件源连接到脚本, 使事件能够被处理.

ComObjConnect ComObj , PrefixOrSink

参数

ComObj

类型: ComObject

产生事件的对象.

如果对象不支持 IConnectionPointContainer 接口, 或无法获取对象类的类型信息, 将显示一条错误信息. 可通过 try/catch 禁止或处理此错误信息.

如果对象支持, 使用 IProvideClassInfo 接口以接收此对象类的类型信息. 否则, ComObjConnect 尝试通过对象的 IDispatch 接口以接收类型信息, 这可能不可靠.

PrefixOrSink

类型: 字符串对象

如果省略, 则对象为 "disconnected"; 即脚本将不再接收其事件通知. 否则, 当事件发生时, 指定一个用于确定调用哪个全局函数的前缀字符串, 或者一个事件接收对象, 为要处理的每个事件定义一个静态方法.

注意: 在此模式下不支持嵌套函数, 因为名称可能在当前函数返回后解析. 要使用嵌套函数或闭包, 请将它们附加到一个对象上, 并按照下面的描述传递该对象.

用法

为了有效地使用 ComObjConnect, 您必须首先在脚本中编写函数来处理任何感兴趣的事件. 这些函数或 "事件处理程序", 具有下列结构:

PrefixEventName([Params..., ComObj])
{
    ... 事件处理代码 ...
    return ReturnValue
}

如果是字符串, Prefix 应该与 PrefixOrSink 参数相同; 否则, 它应该被省略. EventName 应该替换为函数应该处理的任何事件的名称.

Params 对应于事件拥有的任何参数. 如果事件没有参数, 则应该完全忽略 Params. ComObj 是一个额外的参数, 它包含对传递给 ComObjConnect 的原始封装对象的引用, 它从未被包含在 COM 事件的文档中. "ComObj" 应该替换为在您的脚本上下文中更有意义的名称.

注意, 事件处理程序可能有返回值. 要返回特定的 COM 类型的值, 使用 ComValue(). 例如, return ComValue(0,0) 返回一个 VT_EMPTY 类型的变体, 相当于从一个 JavaScript 函数返回 undefined(或没有返回).

调用 ComObjConnect(yourObject, "Prefix") 来启用事件处理.

调用 ComObjConnect(yourObject) 来断开对象(停止处理事件).

如果参数的数目未知, 可以使用可变参数函数.

事件接收

如果 PrefixOrSink 是一个对象, 则每当引发事件时, 就会调用该对象的相应方法. 虽然对象可以动态构造, 但 PrefixOrSink 更典型的做法是引用一个类或类的实例. 在这种情况下, 方法的定义如上所示, 但没有 Prefix.

与对方法的任何调用一样, 方法的(通常是隐藏的) this 参数包含对方法调用所通过的对象的引用; 即事件接收器对象, 而不是 COM 对象. 这可用于为事件处理程序提供上下文, 或在它们之间共享值.

要捕获所有事件而不为每个事件定义方法, 请定义 __Call 元函数.

如果 COM 对象释放连接, ComObject 会自动释放它对 PrefixOrSink 的引用. 例如, Internet Explorer 在退出时就会这样做. 如果脚本不保留自己对 PrefixOrSink 的引用, 它可以使用 __Delete 来检测何时发生这种情况. 如果该对象由远程进程托管, 并且该进程意外终止, 则系统可能需要几分钟才能释放连接.

备注

脚本必须保留对 ComObj 的引用, 否则它将自动释放, 并与其 COM 对象断开连接, 从而阻止任何进一步的事件被检测到. 没有标准的方法来检测何时不再需要连接, 所以脚本必须通过调用 ComObjConnect 手动断开连接.

可能需要使用 Persistent 函数, 以便在脚本监听事件时保持脚本运行.

失败时抛出异常.

ComObject, ComObjGet, ComObjActive, WScript.ConnectObject (Microsoft Docs)

示例

启动 Internet Explorer 的实例, 并将事件连接到相应的前缀为 "IE_" 的脚本函数. 有关 COM 对象和下面使用的 DocumentComplete 事件的详情, 请参阅 InternetExplorer object (Microsoft Docs).

ie := ComObject("InternetExplorer.Application")

; 将事件连接到相应的 "IE_" 为前缀的脚本函数.
ComObjConnect(ie, "IE_")

ie.Visible := true  ; 此语句在 IE7 中无法正常执行.
ie.Navigate("https://www.autohotkey.com/")
Persistent

IE_DocumentComplete(ieEventParam, &url, ieFinalParam) {
    ; IE 传递的 url 作为 VARIANT 的引用, 因此在上面使用 &url
    ; 以便下面的代码可以自然地引用它,而不是使用 %url%.
    s := ""
    if (ie != ieEventParam)
        s .= "First parameter is a new wrapper object.`n"
    if (ie == ieFinalParam)
        s .= "Final parameter is the original wrapper object.`n"
    if (ComObjValue(ieEventParam) == ComObjValue(ieFinalParam))
        s .= "Both wrapper objects refer to the same IDispatch instance.`n"
    MsgBox s . "Finished loading " ie.Document.title " @ " url
    ie.Quit()
    ExitApp
}