在Internet Explorer的内容插件中的可编写脚本对象 [英] scriptable objects in internet explorer content plugin

查看:207
本文介绍了在Internet Explorer的内容插件中的可编写脚本对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然有许多浏览器辅助对象的指南,我很难找到资源,如何实现脚本对象(即除了主控制)内容插件(即嵌入网站)。

为了避免误解:问题是关于可写对象,插件对象可能会返回到网站中的脚本,例如从方法调用。

While there are many guides for Browser Helper Objects, i have a hard time finding resources on how to implement scriptable objects (i.e. besides the main control) for content plugins (i.e. embedded in website).
To avoid misunderstandings: the question is about scriptable objects that a plugin object may return to the scripts in a website, e.g. from a method call.

虽然我猜一般的脚本性这些可能工作通过通常的 IDispatch 看看事件如何处理(即 attachEvent )。你应该手动实现(例如,显式地处理对 attachEvent 的调用)还是只有某些接口必须实现?

While i guess scriptability in general for these probably works via the usual IDispatch, i don't see how events are to be handled (i.e. for attachEvent). Are you supposed to implement that manually (e.g. handle calls to attachEvent explicitly) or are there only certain Interfaces that you have to implement?

推荐答案

更新(从外挂程式发出活动)



好的, gf's 评论,我看到所需的机制是来自DOM外部提供的组件的相反的事件。

Update (issuing events from plugins)

Ok, so with gf's additional comments, I see that the desired mechanism is the opposite- issuing events from components provided outside of the DOM.

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

This is similar in respect to how MSHTML events can be handled, but the plugin's objects will need to inspect objects given to it using a different mechanism.

在提供事件的对象上(或支持为事件附加对象),提供attachEvent和detachEvent方法通过IDispatch(如果需要通过双界面)。如果你想让它与HTML元素无缝地显示,那么你应该声明它们,就像它们在IHTMLElement上提供的一样。 DISPID不必匹配,但参数和类型的顺序应该匹配。

On the objects that provide events (or support attaching objects for events), provide attachEvent and detachEvent methods through IDispatch (and through dual-interface if desired). If you want this to appear seamless with HTML elements, then you should declare them the same way as they are provided on IHTMLElement. The DISPIDs don't have to match but the order of arguments and types should match.

attachEvent方法(IHTMLElement2)@ MSDN

detachEvent方法(IHTMLElement2)@ MSDN

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

(from MSHTML.IDL in the platform SDK)

[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接收调用时,您需要清除对象与事件名的关联。

When you receive a call via attachEvent, you will need to associate the event name with the object received. Similarly, you will need to clear an association of the object to event name when you receive a call via detachEvent.

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

When you look to issue an event, examine all the objects you have stored for methods that should be called, matching your event. In theory you don't have to use the same method name as your event name, but in practice it will be easier to maintain and manage if you do. First examine IDispatch itself, calling GetIDsOfNames() to find an exact match for your event. If not, examine IDispatchEx and look for an expando method via GetDispID() that is a match for your event.

IDispatch Interface @ MSDN

IDispatch :: GetIDsOfNames @ MSDN (查找收件人事件方法)

IDispatchEx Interface @ MSDN

IDispatchEx :: GetDispID @ MSDN (查找收件人事件方法)

IDispatch Interface @ MSDN
IDispatch::GetIDsOfNames @ MSDN (locate recipient event method)
IDispatchEx Interface @ MSDN
IDispatchEx::GetDispID @ MSDN (locate recipient event method)

最后,一旦您找到一个另一个,调用相关的Invoke()方法。

Last, once you have located the handler from one or the other, call the associated Invoke() method.

IDispatch :: Invoke @ MSDN

IDispatchEx :: InvokeEx @ MSDN

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

Most event handler objects are created manually, as this allows them to accept MSHTML events via IDispatch when receiving calls through attachEvent() or when assigned to event properties. This mechanism varies from the typical ConnectionPointContainer to EventSink setup that is prevalent in COM. However, creating an object to handle these events is simpler. There are some key differences you should note if you are going to create such an object to handle an event.


  1. 第一个约束是接收的事件的DISPID和方法名称必须与接收的事件的DISPID和方法匹配。文档在这方面有些稀疏,但是解决正确DISPID的最好的地方是查看C ++头文件。如果您已安装Microsoft Platform SDK,则可以在文件< mshtmdid.h> (MSHTML Dispatch ID的缩写)中查看include子目录。它包含所有相关MSHTML调度ID的列表。

  1. The first constraint is that the DISPID and method name of the event received must match the DISPID and method for the event received. Documentation is somewhat sparse on this, but the best place to resolve the correct DISPID is to look at the C++ header files. If you have the Microsoft Platform SDK installed, you can look inside the include subdirectory at the file <mshtmdid.h> (short for MSHTML Dispatch ID). It contains a list of all the relevant MSHTML dispatch IDs.

第二个约束是IE / MSHTML不会调用vtable-因此调用将通过IDispatch :: Invoke()到达。这可能是一个问题,如果你想要的COM框架不负责路由两个类型的调用到同一处理程序在代码中。

The second constraint is that IE/MSHTML does not call the binary version of methods declared in vtable-based interfaces, so the call will arrive via IDispatch::Invoke(). This might be an issue for you if your desired framework for COM doesn't take care of routing both types of calls to the same handler in your code.

要创建处理程序对象,需要创建一个支持IUnknown,IDispatch和IObjectSafety的COM对象。

To create a handler object, you need to create a COM object that supports IUnknown, IDispatch, and IObjectSafety. IUnknown is implicit for either of the other interfaces, but don't forget IObjectSafety.

没有特别要求,但是你的对象应该是一个公寓的线程对象,以避免头痛。因为通过VARIANT包装器直接调用IDispatch,如果你正在做需要多个公寓的事情,或者你想使用自由线程组件,你可能会遇到问题。大多数框架创建这个模型的对象或默认建议这种类型(VB6,Delphi,MFC,ATL)。

Not specifically required, but your object should be an apartment-threaded object, to avoid marshaling headaches. Since calls are direct to IDispatch via a VARIANT wrapper, you may encounter issues if you are doing things that require multiple apartments or if you are trying to use free-threaded components. Most frameworks create objects for this model or suggest this type by default (VB6, Delp MFC, ATL).

上述C ++头文件中的定义完全对应于IHTMLElement上列出的项目。

Definitions in the C++ header file mentioned above correspond exactly to items listed on IHTMLElement. Here is one specific item to get you started.

首先,HTML DOM元素的事件。

First, the event off of the HTML DOM element.

onclick Property(IHTMLElement)@ MSDN

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

We note that the name of this property is onclick. Now, to the header file.

MSHTMDID.H @ DDART.NET

我们想要的匹配项是 DISPID_EVMETH_ONCLICK 这里:Dispatch ID => Event Method => OnClick)。根据源文件,它通过宏定义重用现有的定义。

The matching item we want is DISPID_EVMETH_ONCLICK (Note the heuristic here: Dispatch ID => Event Method => OnClick). According to the source file, it reuses an existing definition by macro definition.

#define DISPID_EVMETH_ONCLICK                DISPID_CLICK

一些定义重叠或重复使用为一般ActiveX / OLE控件使用定义的相同DISPID。 DISPID_CLICK 在OleCtl.h中定义,所以让我们在那里跟踪最终的值。这个头文件也可以在Platform SDK中使用,并且在VC ++安装中默认包含,至少早在VC ++ 6.0,我记得。

Some of the definitions overlap or recycle the same DISPIDs defined for general ActiveX/OLE control use. DISPID_CLICK is defined in OleCtl.h, so let's head over there to track down the final value. This header file is also available in the Platform SDK and is also included by default in VC++ installations, at least as far back as VC++ 6.0, as I recall.

OLECTL.H @ DDART.NET

我们想要的DISPID是-600。

The DISPID we want is -600.

#define DISPID_CLICK                    (-600)

现在,在组件的IDL中,您需要声明一个名为onclick()的方法这个DISPID值;或者您将需要在IDispatch :: Invoke()的处理程序中处理此DISPID。如果你使用ATL,它不伤害声明的方法和提供双布局。其他实现可能有所不同。

Now, in the IDL for your component, you will either need to declare a method called onclick(), that has this DISPID value; or you will need to handle this DISPID in your handler for IDispatch::Invoke(). If you are using ATL, it doesn't hurt to declare the method and provide dual-layout. Other implementations may vary.

您的开发的其余部分应该是典型的在Internet Explorer中脚本对象。另请注意,这些DISPID中的大多数属于负值范围,以避免与用户定义的DISPID冲突。

The rest of your development should be typical for scripting objects in Internet Explorer. Also note that most of these DISPIDs fall in the negative range, to avoid collisions with user-defined DISPIDs.

这篇关于在Internet Explorer的内容插件中的可编写脚本对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆