【问题标题】:Is it possible to pass Javascript objects to ActiveX (and use them)?是否可以将 Javascript 对象传递给 ActiveX(并使用它们)?
【发布时间】:2011-12-05 00:00:16
【问题描述】:

我想将 JavaScript 对象(JSON 和函数对象)传递到我的 ActiveX 控件中。理想情况下,我可以操作 JavaScript 对象(例如读取或修改 JSON)并从 ActiveX 控件中执行 JavaScript 函数调用(使用 C++)。这有可能吗,还是我必须接受传递字符串?

例如,这是我可以在 Firefox 中执行的操作。请注意,我有一个 JSON 对象的引用,而且我还可以执行 JavaScript 函数调用:

NPString jsonToString(NPP instance, NPObject* json)
{
    NPVariant result;
    NPVariant arg;
    NPIdentifier identifier;

    /* Get the global object */
    NPObject* windowObj = NULL;
    g_NPNFuncs.getvalue(instance, NPNVWindowNPObject, &windowObj);

    /* Get JSON object */
    identifier = g_NPNFuncs.getstringidentifier("JSON");
    g_NPNFuncs.getproperty(instance, windowObj, identifier, &result);
    NPObject* jsonObj = NPVARIANT_TO_OBJECT(result);

    /* Call stringify */
    identifier = g_NPNFuncs.getstringidentifier("stringify");
    OBJECT_TO_NPVARIANT(json, arg);
    g_NPNFuncs.invoke(instance, jsonObj, identifier, &arg, 1, &result);

    return NPVARIANT_TO_STRING(result);
}


编辑 - 这是我想出的解决方案:

IDL 文件:

[id(TEST_ID)] BSTR Test(BSTR data, IDispatch* function);


调度图:

DISP_FUNCTION_ID(CApp, "test", TEST_ID, Test, VT_BSTR, VTS_BSTR VTS_DISPATCH)


接口函数:

BSTR Test(BSTR data, IDispatch* function)


调用 JavaScript 函数对象:

VARIANTARG args[1];
args[0].vt = VT_BSTR;
args[0].bstrVal = _bstr_t(dataStr).GetBSTR();

DISPPARAMS params;
params.cArgs = 1;
params.cNamedArgs = 0;
params.rgvarg = args;

HRESULT hresult = function->Invoke(0, IID_NULL,
    LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

使用 DISPID 为 0 调用 IDispatch::Invoke 似乎适用于调用函数对象。但是,要调用一个对象的方法,就得先得到对应的DISPID,正如Taxilian所说。 GetNextDispID 应该可以解决这个问题(IDispatchEx 的第一个 QueryInterface;转换为 IDispatchEx 似乎也可以,但可能不安全)。

【问题讨论】:

  • 你应该看看这个问题:Passing array of bytes from ActiveX to javascript and vice versa。只要你“字符串化”你的对象,并将它作为一个字符串(obv)传递,你就是金色的。
  • 是的,我看到了这个问题。 Stringify 不一定是我唯一想做的事情;这只是一个例子。也就是说,如果这被证明太复杂,我最终可能只是传递字符串。

标签: javascript c++ mfc activex npapi


【解决方案1】:

哇,我今天显然不是很聪明,因为我刚刚写了一个答案,完全错过了你说 npapi 插件代码是一个例子的部分 =]

所以,要回答正确的问题,是的,您可以。 ActiveX 中与 NPObject 最相关的类型是IDispatch(或IDispatchEx)。您只需调用 Invoke 并告诉它是否应该获取属性、设置属性或调用方法,而不是拥有 GetProperty、SetProperty 和 Invoke。您首先必须查询以获取相关成员的 DISPID;与 NPIdentifier 类似,DISPID 是字符串和数字之间的映射。

如果你还没有看过它,你应该看看FireBreath,它提供了一个抽象,允许你编写一个插件,它可以在具有相同代码库的 NPAPI 和 ActiveX 上运行。它有一个 wrapper to allow it to use IDispatch objects 作为示例,您可能会发现它很有用。

长话短说,您可以使用 IDispatch(或者更好的是 IDispatchEx)来使用 JS 对象,就像使用 NPObject 一样。大多数来自 javascript 的东西都是通过 IDispatchEx 实现的,但偶尔我也看到需要 IDispatch 故障转移支持的实例。

希望它有所帮助,我希望我最初的回答(在我重新阅读你的问题之前)没有让你失望。

【讨论】:

  • 所以我在我的接口(在 IDL 文件中定义)的一个函数中添加了一个 IDispatch* 参数。然后我将它转换为 IDispatchEx(无法在 IDL 中指定它,因为它似乎不喜欢 DispEx.h 标头)。这一切似乎都还好。但是,如果我传入一个 JavaScript 函数对象,你知道如何调用它吗? GetNextDispID 不返回任何成员。顺便说一句,FireBreath 代码有助于查看 - 太糟糕了,由于业务问题,我暂时无法使用它。
  • 没关系,我发现我可以从这里调用 dispid 为 0:stackoverflow.com/questions/1681327/…
猜你喜欢
  • 2020-01-04
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-16
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
相关资源
最近更新 更多