继续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);
编辑:试图澄清这个问题。
答案 0 :(得分:3)
如果脚本一致地定义对象,则从脚本调用对象应该是可靠的。对于MSHTML中的JScript / Javascript应该是这种情况,但不幸的是,关于这个主题的文档确实很少,我手边没有任何可靠的证据。
根据我自己的经验,传递给attachEvent()的Javascript函数应始终保持一致 - 接收的对象是'function',只能有一个匹配自身的可调用方法。因此,默认方法是唯一可以找到的方法,DISPID为0. Javascript函数通常不具有成员函数,但我确信有一种方法可以实现。如果它确实有成员函数,您将看到它们与对象上的成员函数相同。根据expando函数的规则,JScript中的成员函数将始终与IDispatchEx保持一致,因为添加到对象的任何函数都算作expandos。
答案 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咒语,它是一个很好的参考。