# ComObjConnect() [AHK_L 53+]

链接 COM 对象的事件到给定的前缀名的响应函数.

    ComObjConnect(ComObject , Prefix)

## 参数

ComObject

  产生事件的对象.

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

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

Prefix

  用于确定当事件发生时应调用哪个函数, 此字符串为事件名称(EventName) 对应的前缀(Prefix) .

  如果省略, 则对象为 "未连接的"; 即脚本将不再接收其事件通知.

  [v1.1.01+]: 此参数可以为脚本定义的对象. 事件发生时, 会调用相应的方法. 首个参数, 通常为隐式传递的参数 `this`, 其引用脚本定义的对象, 而非 COM 对象. 要捕获所有事件, 而又不想为每个事件定义方法, 可定义 __Call 元函数.

## 用法

在脚本中编写处理所需事件的函数. 这类函数或 "事件处理程序" 具有下列结构:

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

Prefix(前缀) 为用户定义; 而 EventName(事件名称) 为期望此函数响应的事件名称, 定义于产生事件的对象.

Params(参数) 对应于事件包含的所有参数. 如果事件不含有参数, Params 应完全省略. ComObject 为可选, 仅当 Params 的数目正确时; 它包含了到传递给 ComObjConnect 的原始包装器(转换器) 对象的引用. "ComObject"应被替换为与您脚本上下文相关的更有意义的名称.

注意, 事件处理程序可以产生返回值. 要返回特定的 COM 类型的值, 使用 ComObject(Type, Value). 例如, `return ComObject(0,0)` 返回类型为 VT_EMPTY 的变体, 其等效于从 JavaScript 函数中返回 `undefined`(或未返回).

调用 `ComObjConnect(目标对象, "Prefix")` 以启用事件处理.

调用 `ComObjConnect(目标对象)` 以断开对象(停止事件处理).

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

## 备注

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

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

失败时, 函数可能会抛出异常, 退出脚本或返回空字符串, 具体取决于当前的 ComObjError() 设置和其他因素.

## 相关

ComObjCreate(), ComObjGet(), ComObjActive(), ComObjError(), WScript.ConnectObject (MSDN)

## 示例

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

    ie := ComObjCreate("InternetExplorer.Application")

    ; 把事件连接到带 "IE_" 前缀的脚本函数.
    ComObjConnect(ie, "IE_")

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

    IE_DocumentComplete(ieEventParam, url, ieFinalParam) {
        global ie
        if (ie != ieEventParam)
            s .= "第一个参数是新的包装器对象.`n"
        if (ie == ieFinalParam)
            s .= "最后一个参数是原始包装器对象.`n"
        if ((disp1:=ComObjUnwrap(ieEventParam)) == (disp2:=ComObjUnwrap(ieFinalParam)))
            s .= "两个包装器对象均引用同一个 IDispatch 实例.`n"
        ObjRelease(disp1), ObjRelease(disp2)
        MsgBox % s . "完成载入" ie.Document.title " @ " url
        ie.Quit()
        ExitApp
    }

dftg