从脚本调用IDispatchs时,DISPID_VALUE是否可靠?

时间:2009-11-05 15:35:07

标签: c++ internet-explorer com activex

继续this question,我很困惑DISPID_VALUE IDispatch::Invoke()对于脚本函数和属性(在我的情况下是JavaScript)是否可以被认为是调用实际函数的标准和可靠的代表IDispatch
如果是,是否在MSDN的任何地方提到过?

请注意,问题是关于是否可以预期这种行为,而不是事先我不知道的某些界面可能是什么样的。

一个简单的用例是:

// usage in JavaScript
myObject.attachEvent("TestEvent", function() { alert("rhubarb"); }); 

// handler in ActiveX, MyObject::attachEvent(), C++
incomingDispatch->Invoke(DISPID_VALUE, IID_NULL, LOCALE_SYSTEM_DEFAULT,
                         DISPATCH_METHOD, par, res, ex, err);

编辑:试图澄清这个问题。

4 个答案:

答案 0 :(得分:3)

如果脚本一致地定义对象,则从脚本调用对象应该是可靠的。对于MSHTML中的JScript / Javascript应该是这种情况,但不幸的是,关于这个主题的文档确实很少,我手边没有任何可靠的证据。

根据我自己的经验,传递给attachEvent()的Javascript函数应始终保持一致 - 接收的对象是'function',只能有一个匹配自身的可调用方法。因此,默认方法是唯一可以找到的方法,DISPID为0. Javascript函数通常不具有成员函数,但我确信有一种方法可以实现。如果它确实有成员函数,您将看到它们与对象上的成员函数相同。根据expando函数的规则,JScript中的成员函数将始终与IDispatchEx保持一致,因为添加到对象的任何函数都算作expandos。

IDispatchEx interface @ MSDN

答案 1 :(得分:2)

DISPID_VALUE调用的默认方法或属性对于给定的接口应该是一致的。必须在类型库的IDL中的接口定义中将该方法/属性指定为DISPID_VALUE。它可以改变的唯一方法是,如果接口的所有者发布了一个新版本的接口,它改变了哪个方法/属性是默认的,但这违反了COM接口的基本规则。

答案 2 :(得分:1)

正如meklarian所说,DISPID_VALUE(0)似乎对JS函数非常有效(因此它适用于自定义attachEvent)。我用这种方式已经用了大约一年了,而且它总能奏效。我还发现嵌入了<object>标签的activeX控件使其能够一致地工作,我需要为主(对象标签)IDispatch实现CComObject实现IConnectionPointContainer和IConnectionPoint,但是其他任何我暴露于javascript作为方法或属性的返回值(通过Invoke)我必须自己实现attachEvent和detachEvent。

使用连接点时,有问题的IDispatch对象会将事件触发到与IDispatch对象上附加的DISPID相同的DISPID。

请参阅http://code.google.com/p/firebreath/source/browse/src/ActiveXPlugin/JSAPI_IDispatchEx.h以获取实施ConnectionPoints的示例。

答案 3 :(得分:0)

您可以将DISPID添加到DISPINTERFACE,但是一旦发布就无法更改它们。如果需要,可以使用IDispatch::GetIDsOfNames将名称映射到DISPID。

获取一份Inside Ole(第二版)和Inside Ole 2(第二版)的副本,用于在亚马逊上使用的几块钱。对于这些不起眼的OLE咒语,它是一个很好的参考。