2011-10-11 30 views
3

我想将JavaScript对象(JSON和函数对象)传入我的ActiveX控件。理想情况下,我可以操纵JavaScript对象(例如读取或修改JSON),并从ActiveX控件内部执行JavaScript函数调用(使用C++)。这是否有可能,还是我必须解决通过字符串?是否有可能将JavaScript对象传递给ActiveX(并使用它们)?

例如,以下是我在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); 

调用的IDispatch ::为0的DISPID调用似乎对调用工作函数对象。但是,要调用对象的方法,您必须首先获得相应的DISPID,正如Taxilian所说。 GetNextDispID应该为此工作(IDispatchEx的第一个QueryInterface;转换为IDispatchEx似乎也可以,但也许不安全)。

+0

你应该看看这个问题:[从ActiveX传递字节数组到JavaScript,反之亦然](http:// stackoverflow。COM /问题/ 1926723 /通过阵列 - 的字节从 - 的ActiveX到的JavaScript和 - 反之亦然)。只要你'串化'你的对象,并将其作为字符串(obv)传递,你就是金。 –

+0

是的,我看到了这个问题。字符串化不一定是我想要做的唯一事情;这只是一个例子。也就是说,如果事实证明这太复杂,我最终可能会传递字符串。 –

回答

2

哇,我今天aparently不是很亮,因为我只是写了一个答案完全缺失的,你说的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故障转移的实例。

希望它有帮助,并且我希望我的初步反应(在我重新阅读您的问题之前)没有让您失望。

+0

所以我在接口中的函数中添加了一个IDispatch *参数(在IDL文件中定义)。然后我将它铸造成IDispatchEx(无法在IDL中指定它,因为它似乎不喜欢DispEx.h头文件)。这一切似乎都没有问题。但是,如果我传入JavaScript函数对象,您是否有任何想法如何调用它? GetNextDispID不返回任何成员。顺便说一句,FireBreath代码有助于我们研究 - 这太糟糕了,由于商业问题,我暂时无法使用它。 –

+0

没关系,我发现我可以从这里调用dispid 0:http://stackoverflow.com/questions/1681327/is-dispid-value-reliable-for-invokes-on-idispatchs-from-scripts –

相关问题