Internet Explorer 内容插件中的可编写脚本的对象

2024-01-12

虽然浏览器帮助程序对象有很多指南,但我很难找到有关如何为内容插件(即嵌入在网站中)实现可编写脚本的对象(即除了主控件之外)的资源。
为了避免误解:问题是关于插件对象可能返回到网站中的脚本的可脚本化对象,例如来自方法调用。

虽然我猜想这些的一般可脚本性可能通过通常的方式工作IDispatch,我不知道如何处理事件(即attachEvent)。您是否应该手动实现(例如处理对attachEvent明确地)或者您只需要实现某些接口?


更新(从插件发出事件)

好的,所以与gf's附加评论,我发现所需的机制是相反的 - 从 DOM 外部提供的组件发出事件。

这与处理 MSHTML 事件的方式类似,但插件的对象需要使用不同的机制检查提供给它的对象。

在提供事件(或支持为事件附加对象)的对象上,通过 IDispatch(如果需要,还可以通过双接口)提供 AttachEvent 和 detachEvent 方法。如果您希望它与 HTML 元素无缝显示,那么您应该以与 IHTMLElement 上提供的相同方式声明它们。 DISPID 不必匹配,但参数和类型的顺序应该匹配。

AttachEvent 方法 (IHTMLElement2) @ MSDN http://msdn.microsoft.com/en-us/library/aa703974%28VS.85%29.aspx
detachEvent 方法 (IHTMLElement2) @ MSDN http://msdn.microsoft.com/en-us/library/aa703981%28VS.85%29.aspx

(来自平台SDK中的MSHTML.IDL)

[id(DISPID_IHTMLELEMENT2_ATTACHEVENT)] HRESULT attachEvent(
  [in] BSTR event,
  [in] IDispatch* pDisp,
  [retval, out] VARIANT_BOOL* pfResult);
[id(DISPID_IHTMLELEMENT2_DETACHEVENT)] HRESULT detachEvent(
  [in] BSTR event,
  [in] IDispatch* pDisp);

当您通过 AttachEvent 收到调用时,您需要将事件名称与收到的对象关联起来。同样,当您通过 detachEvent 收到调用时,您需要清除对象与事件名称的关联。

当您希望发出事件时,请检查您存储的所有对象,以查找与您的事件相匹配的应调用的方法。理论上,您不必使用与事件名称相同的方法名称,但实际上,如果这样做,维护和管理会更容易。首先检查 IDispatch 本身,调用 GetIDsOfNames() 来查找与您的事件完全匹配的内容。如果没有,请检查 IDispatchEx 并通过 GetDispID() 查找与您的事件匹配的 Expando 方法。

IDispatch 接口@MSDN http://msdn.microsoft.com/en-us/library/ms221608.aspx
IDispatch::GetIDsOfNames @ MSDN http://msdn.microsoft.com/en-us/library/ms221306.aspx(定位接收者事件方法)
IDispatchEx 接口@MSDN http://msdn.microsoft.com/en-us/library/sky96ah7%28VS.80%29.aspx
IDispatchEx::GetDispID @ MSDN http://msdn.microsoft.com/en-us/library/wwazwk2k%28VS.85%29.aspx(定位接收者事件方法)

最后,一旦找到其中一个处理程序,就调用关联的 Invoke() 方法。

IDispatch::调用@MSDN http://msdn.microsoft.com/en-us/library/ms221479.aspx
IDispatchEx::InvokeEx @ MSDN http://msdn.microsoft.com/en-us/library/asd22sd4%28VS.85%29.aspx

初始(处理预定义的 MSHTML 事件)

大多数事件处理程序对象都是手动创建的,因为这允许它们在通过attachEvent()接收调用或分配给事件属性时通过IDispatch接受MSHTML事件。此机制不同于 COM 中流行的典型 ConnectionPointContainer 和 EventSink 设置。然而,创建一个对象来处理这些事件更简单。如果您要创建这样的对象来处理事件,则应该注意一些关键差异。

  1. 第一个约束是接收到的事件的 DISPID 和方法名称必须与接收到的事件的 DISPID 和方法匹配。关于这一点的文档有些稀疏,但解析正确 DISPID 的最佳位置是查看 C++ 头文件。如果您安装了 Microsoft Platform SDK,您可以查看 include 子目录中的文件(MSHTML 调度 ID 的缩写)。它包含所有相关 MSHTML 调度 ID 的列表。

  2. 第二个限制是 IE/MSHTML 不会调用基于 vtable 的接口中声明的方法的二进制版本,因此调用将通过 IDispatch::Invoke() 到达。如果您所需的 COM 框架不负责将两种类型的调用路由到代码中的同一处理程序,这对您来说可能是个问题。

  3. 要创建处理程序对象,您需要创建支持 IUnknown、IDispatch 和 IObjectSafety 的 COM 对象。 IUnknown 对于其他任何一个接口都是隐式的,但不要忘记 IObjectSafety。

  4. 没有特别要求,但您的对象应该是公寓线程对象,以避免编组问题。由于调用是通过 VARIANT 包装器直接调用 IDispatch,因此如果您正在执行需要多个单元的操作或尝试使用自由线程组件,则可能会遇到问题。大多数框架为此模型创建对象或默认建议这种类型(VB6、Delphi、MFC、ATL)。

上述 C++ 头文件中的定义与 IHTMLElement 上列出的项目完全对应。这是一个帮助您入门的具体项目。

首先,HTML DOM 元素的事件关闭。

onclick 属性 (IHTMLElement) @ MSDN http://msdn.microsoft.com/en-us/library/aa752306%28VS.85%29.aspx

我们注意到这个属性的名称是onclick。现在,到头文件。

MSHTMDID.H @ DDART.NET http://doc.ddart.net/msdn/header/include/mshtmdid.h.html

我们想要的匹配项是DISPID_EVMETH_ONCLICK(请注意此处的启发式:调度 ID => 事件方法 => OnClick)。根据源文件,它通过宏定义重用了现有的定义。

#define DISPID_EVMETH_ONCLICK                DISPID_CLICK

某些定义重叠或重复使用为一般 ActiveX/OLE 控件使用定义的相同 DISPID。DISPID_CLICK是在 OleCtl.h 中定义的,所以让我们去那里追踪最终值。这个头文件也可以在 Platform SDK 中找到,并且默认情况下也包含在 VC++ 安装中,据我所知,至少可以追溯到 VC++ 6.0。

OLECTL.H @ DDART.NET http://doc.ddart.net/msdn/header/include/olectl.h.html

我们想要的 DISPID 是 -600。

#define DISPID_CLICK                    (-600)

现在,在组件的 IDL 中,您需要声明一个名为 onclick() 的方法,该方法具有此 DISPID 值;或者您需要在 IDispatch::Invoke() 的处理程序中处理此 DISPID。如果您使用 ATL,声明方法并提供双重布局也没有什么坏处。其他实现可能会有所不同。

开发的其余部分应该与 Internet Explorer 中的脚本对象典型相同。另请注意,大多数 DISPID 都处于负值范围内,以避免与用户定义的 DISPID 发生冲突。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Internet Explorer 内容插件中的可编写脚本的对象 的相关文章

随机推荐

  • 从 R 调用 .NET/C#

    我想使用仅在 NET 中可用的 R API 是否有可用于从 R 调用 NET C 代码的标准方法 如果是这样 我该怎么做 本讨论的读者可能会考虑的另一个选择是rClr 包 https github com jmp75 rClr 我已经研究了
  • 实体框架 CTP5,代码优先。可选的导航属性

    我正在使用实体框架 CTP5 代码优先 并且我有两个类 public class Order public int Id get set public decimal SomeOtherProperty1 get set navigatio
  • AWS Elastic Beanstalk NodeJS 和日志

    我想将我的 NodeJS 项目从单个 EC2 迁移到 ElasticBeanstalk 在我当前的代码中 我使用依赖项 log4js 在文件系统上创建日志文件 在 EC2 上 这可以创建 但在 ElasticBeanstalk 中记录某些内
  • CLion 项目中所有错误的列表

    CLion 2016 2 有助于检测您正在编辑的文件中的潜在错误 这些错误可以在代码右侧的验证栏中看到 但这只是一个文件 有没有办法 如工具窗口 来获取整个项目或其特定部分中所有此类警告的列表 如果它还列出了编译器的警告和错误 那就加分了
  • 如何在引导的 Firefox 扩展中实现 XPCOM 组件 (nsIContentPolicy)

    我有一个 Firefox 的引导扩展 现在我想实现 nsIContentPolicy XPCOM 组件 我写了一个组件模块代码 现在我想注册这个组件 我想注册组件的原因是我想将我的组件添加到nsICategoryManager addCat
  • Kubernetes 作业被创建但不会立即执行

    例如 创建如下所示的就业机会 apiVersion batch v1 kind Job metadata name test job sebas spec template spec containers name pi image per
  • OpenCV Mat 处理时间

    我想知道 OpenCV 函数的 src 源 和 dst 目标 使用不同的变量是否会对处理时间产生影响 我有下面两个函数 做同样的事情 public static Mat getY Mat m Mat mMattemp new Mat Img
  • Swift 2.0 中的 do { } catch 不会处理从这里抛出的错误

    更新 swift 2 0 后 我遇到了 do try catch 错误 如下图所示 我怎样才能解决这个问题 谢谢 该错误告诉您封闭的捕获并不详尽 这是因为自动生成的catch块只是捕获NSError对象 编译器无法判断是否有其他对象Erro
  • 变基以及变基推送提交意味着什么

    人们常说 您不应该对已经推送的提交进行变基 这可能意味着什么 To understand this we need to understand a bit about how git works A git repository is a
  • 如何使用 Jackson 和 Spring Boot 提供自定义反序列化器

    我有以下三个应用程序 项目1举行 业务逻辑 Spring Cloud Function 一个接口IDemo实体 项目2 AWS 特定的处理程序 一种实现IDemo实体 带有 DynamoDB 特定的注释 该项目基于Spring Boot 项
  • 如何在 chromedriver 中启用地理定位支持?

    我需要使用 Selenium 测试 JS 地理定位功能 并且我正在使用 chromedriver 在最新的 Chrome 上运行测试 现在的问题是 Chrome 提示我在测试期间启用地理定位 并且我不知道如何在运行时单击那个小栏 所以我拼命
  • Prolog:访问从父规则读取

    我想要一个特定的规则来读取 SWI Prolog 中的用户输入数据 例如 process do stuff read values do more stuff with X and Y here read values write Plea
  • 如何让自定义任务标签在 Eclipse 中工作?

    尝试了很多次 但我就是不知道如何在任务中定义自定义标签 我使用该对话框并创建了不同的内容 例如 TODO2 V2 或 TOVO 仅用于测试 但这些都不会扫描到任务 即使我做了类似 TODO2 或 源代码中的 V2 或 TOVO 我也尝试过重
  • 开始卡桑德拉——使用昆德拉?还有别的事吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我们正在接触 Cassandra 我们没有人对这个特定平台有任何经验 但都是 JavaEE JPA 等方面经验丰富的开发人员 我遇到了 Kund
  • Pivotal Cloud Foundry 登录问题

    我有一个 PWS 帐户 安装 Cloud Foundry 命令行界面 CLI 后 我尝试从 Windows 命令提示符 CYGWIN 终端和 Gitbash 登录 在上述所有情况下 我都无法登录cf login 但如果我发出命令 我就可以登
  • Grails - 将 UUID 渲染为 JSON

    我使用 UUID 作为我的域类的生成器 当我将域对象呈现为 JSON 时 id 如下所示 id class java util UUID leastSignificantBits 7570618374586820490 mostSignif
  • 在IIS中托管asp.net core应用程序,以便从网络内的其他PC访问

    如何在 Windows IIS 中托管我的 Asp Net Core 1 2 或 2 1 Web 应用程序 以便能够从本地网络 或我的虚拟操作系统 中的其他 PC 访问它 我的电脑是桌面 Windows 10 Pro 不是 Win Serv
  • C++0x 标准中对导出关键字的最佳解释是什么?

    我知道在最初的C 0x标准中有一个功能叫做export 但我找不到这个功能的描述或解释 它应该做什么 另外 哪个编译器支持它 尽管标准 C 没有这样的要求 但某些编译器要求所有函数模板都需要在使用它的每个翻译单元中可用 实际上 对于这些编译
  • 如何关闭 PDF 文件并重新创建它? (使用中的文件)

    我有一个可以创建 PDF 文件的 Java 应用程序 例如 我从程序创建一个简单的文件 我已经构建了代码来打开该文件 所以我创建了该文件 我看到了它 然后就可以了 如果我想修改该文件 我必须关闭该文件然后重新创建它 如果我不关闭该文件 则会
  • Internet Explorer 内容插件中的可编写脚本的对象

    虽然浏览器帮助程序对象有很多指南 但我很难找到有关如何为内容插件 即嵌入在网站中 实现可编写脚本的对象 即除了主控件之外 的资源 为了避免误解 问题是关于插件对象可能返回到网站中的脚本的可脚本化对象 例如来自方法调用 虽然我猜想这些的一般可