我想将JavaScript对象(JSON和函数对象)传递到我的ActiveX控件中。理想情况下,我可以操作JavaScript对象(例如,读取或修改JSON)并从ActiveX控件(使用C ++)执行JavaScript函数调用。这是否有可能,或者我是否必须满足于传递字符串?
例如,这是我在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, ¶ms, NULL, NULL, NULL);
使用DISPID为0调用IDispatch :: Invoke似乎可以用于调用函数对象。但是,要调用对象的方法,您必须首先获得相应的DISPID,正如Taxilian所说。 GetNextDispID应该适用于此(IDispatchEx的第一个QueryInterface;转换为IDispatchEx似乎也可以工作,但可能不安全)。
答案 0 :(得分:1)
所以,回答正确的问题,是的,你可以。最接近NPObject的ActiveX中的类型是IDispatch(或IDispatchEx)。您只需调用Invoke并告诉它是否应获取属性,设置属性或调用方法,而不是使用GetProperty,SetProperty和Invoke。您首先必须查询以获取相关成员的DISPID;类似于NPIdentifier,DISPID是字符串和数字之间的映射。
如果你还没有看到它,你应该看看FireBreath,它提供了一个抽象,允许你编写一个在NPAPI和ActiveX上使用相同代码库的插件。它有一个wrapper to allow it to use IDispatch objects,你可能会觉得它很有用。
长话短说,你可以使用ID对象(甚至更好的IDispatchEx),使用与NPObject相同的方式使用JS对象。来自javascript的大多数内容都是作为IDispatchEx发布的,但偶尔我会看到需要IDispatch故障转移支持的实例。
希望它有所帮助,我希望我的初步回应(在我重新阅读你的问题之前)并没有让你失望。