</head> <body> <h1>ComObjConnect() <span class="ver">[AHK_L 53+]</span></h1> <p>链接 COM 对象的事件到给定的前缀名的响应函数.</p> <pre class="Syntax"><span class="func">ComObjConnect</span>(ComObject <span class="optional">, PrefixOrSink</span>)</pre> <h2 id="Parameters">参数</h2> <dl> <dt>ComObject</dt> <dd> <p>产生事件的对象.</p> <p>如果对象不支持 IConnectionPointContainer 接口, 或无法获取对象类的类型信息, 将显示一条错误信息. 可通过 <a href="ComObjError.htm">ComObjError()</a> 或 <a href="Try.htm">try</a>/<a href="Catch.htm">catch</a> 禁止或处理此错误信息.</p> <p><span class="ver">[v1.1.22+]</span>: 如果对象支持, 使用 IProvideClassInfo 接口以接收此对象类的类型信息. 否则, ComObjConnect 尝试通过对象的 IDispatch 接口以接收类型信息, 这可能不可靠.</p> </dd> <dt>PrefixOrSink</dt> <dd> <p>如果为空或省略, 则对象为 "未连接的"; 即脚本将不再接收其事件通知. 否则, 指定一个作为事件名称前缀的字符串, 用于确定在事件发生时调用哪个函数, 或者 <span class="ver">[在 v1.1.01+]</span> 作为<a href="#event-sink">事件接收对象</a>(为要处理的每个事件定义方法).</p> </dd> </dl> <h2 id="Usage">用法</h2> <p>在脚本中编写处理所需事件的函数. 这类函数或 "事件处理程序" 具有下列结构:</p> <pre class="Syntax Short NoIndent"><i>Prefix</i><b>EventName</b>([<i>Params...</i>, ComObject]) { <i class="dull">... 事件处理代码 ...</i> return <i>ReturnValue</i> }</pre> <p>如果是字符串, <i>Prefix</i> 应该与 <em>PrefixOrSink</em> 参数相同; 否则, 它应该被省略. <b>EventName</b> 应该替换为函数应该处理的任何事件的名称.</p> <p><i>Params(参数)</i> 对应于事件包含的所有参数. 如果事件不含有参数, <i>Params</i> 应完全省略. <i>ComObject</i> 为可选, 仅当 <i>Params</i> 的数目正确时; 它包含了到传递给 ComObjConnect 的原始包装器(转换器) 对象的引用. "ComObject" 应被替换为与您脚本上下文相关的更有意义的名称.</p> <p>注意, 事件处理程序可以产生返回值. 要返回特定的 COM 类型的值, 使用 <a href="ComObjActive.htm#ComObject">ComObject()</a>. 例如, <code>return ComObject(0,0)</code> 返回类型为 VT_EMPTY 的变体, 其等效于从 JavaScript 函数中返回 <code>undefined</code>(或未返回).</p> <p>调用 <code>ComObjConnect(目标对象, "<i>Prefix</i>")</code> 以启用事件处理.</p> <p>调用 <code>ComObjConnect(目标对象)</code> 以断开对象(停止事件处理).</p> <p>如果参数的数目未知, 可用<a href="../Functions.htm#Variadic">可变参数函数</a>.</p> <h3 id="event-sink">Event Sink <span class="ver">[v1.1.01+]</span></h3> <p>如果 <em>PrefixOrSink</em> 是一个对象, 则每当引发事件时, 就会调用该对象的相应方法. 虽然对象可以动态构造, 但 <em>PrefixOrSink</em> 更典型的做法是引用一个类或类的实例. 在这种情况下, 方法的定义如上所示, 但没有 <em>Prefix</em>.</p> <p>与对方法的任何调用一样, 方法的(通常是隐藏的) <code>this</code> 参数包含对方法调用所通过的对象的引用; 即事件接收器对象, 而不是 COM 对象. 这可用于为事件处理程序提供上下文, 或在它们之间共享值.</p> <p>要捕获所有事件而不为每个事件定义方法, 请定义 <a href="../Objects.htm#Meta_Functions">__Call 元函数</a>.</p> <p><em>ComObject</em> 保留了对 <em>PrefixOrSink</em> 的引用, 因此在对象断开连接之前不能删除它.</p> <p><span class="ver">[v1.1.36.02+]</span>: 如果 COM 对象释放连接, <em>ComObject</em> 会自动释放它对 <em>PrefixOrSink</em> 的引用. 例如, Internet Explorer 在退出时就会这样做. 如果脚本不保留自己对 <em>PrefixOrSink</em> 的引用, 它可以使用 <a href="../Objects.htm#Custom_NewDelete">__Delete</a> 来检测何时发生这种情况. 如果该对象由远程进程托管, 并且该进程意外终止, 则系统可能需要几分钟才能释放连接.</p> <h2 id="Remarks">备注</h2> <p>脚本必须保留对 <em>ComObject</em> 的引用, 否则它将自动释放, 并与其 COM 对象断开连接, 从而阻止任何进一步的事件被检测. 没有标准的方法来检测何时不再需要连接, 因此脚本必须通过调用 ComObjConnect 来手动断开连接.</p> <p>可能需要使用 <a href="_Persistent.htm">#Persistent</a> 指令, 以便在脚本监听事件时保持脚本运行.</p> <p>失败时, 函数可能会抛出异常, 退出脚本或返回空字符串, 具体取决于当前的 <a href="ComObjError.htm">ComObjError()</a> 设置和<a href="ComObjError.htm#factors">其他因素</a>.</p> <h2 id="Related">相关</h2> <p><a href="ComObjCreate.htm">ComObjCreate()</a>, <a href="ComObjGet.htm">ComObjGet()</a>, <a href="ComObjActive.htm">ComObjActive()</a>, <a href="ComObjError.htm">ComObjError()</a>, <a href="https://learn.microsoft.com/previous-versions/ccxe1xe6(v=vs.85)">WScript.ConnectObject (Microsoft Docs)</a></p> <h2 id="Examples">示例</h2> <div class="ex" id="ExIE"> <p><a class="ex_number" href="#ExIE"></a> 启动 Internet Explorer 的实例, 并将事件连接到相应的前缀为 "IE_" 的脚本函数. 有关 COM 对象和下面使用的 DocumentComplete 事件的详情, 请参阅 <a href="https://learn.microsoft.com/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa752084(v=vs.85)">InternetExplorer object (Microsoft Docs)</a>.</p> <pre>ie := ComObjCreate("InternetExplorer.Application") <em>; 把事件连接到带 "IE_" 前缀的脚本函数.</em> ComObjConnect(ie, "IE_") ie.Visible := true <em>; 已知此语句在 IE7 上无法正常执行.</em> 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:=<a href="ComObjActive.htm#ComObjUnwrap">ComObjUnwrap</a>(ieEventParam)) == (disp2:=ComObjUnwrap(ieFinalParam))) s .= "两个包装器对象均引用同一个 IDispatch 实例.`n" <a href="ObjAddRef.htm">ObjRelease</a>(disp1), ObjRelease(disp2) MsgBox % s . "完成载入" ie.Document.title " @ " url ie.Quit() ExitApp } </pre> </div> </body> </html>