Можно ли передавать объекты Javascript в ActiveX (и использовать их)? - PullRequest
3 голосов
/ 11 октября 2011

Я хочу передать объекты JavaScript (объекты JSON и функции) в свой элемент управления ActiveX.В идеале я мог бы манипулировать объектами JavaScript (например, читать или изменять JSON) и выполнять вызовы функций JavaScript из элемента управления ActiveX (используя 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);

Вызов IDispatch :: Invoke с DISPID 0, похоже, работает для вызова объекта функции.Однако, чтобы вызвать метод объекта, вы должны сначала получить соответствующий DISPID, как сказал Таксилиан.GetNextDispID должен работать для этого (первый QueryInterface для IDispatchEx; приведение к IDispatchEx, кажется, тоже работает, но, возможно, небезопасно).

1 Ответ

1 голос
/ 11 октября 2011

Ничего себе, я, кажется, сегодня не очень умный, потому что я только что написал ответ, полностью пропустив ту часть, где вы сказали, что код плагина npapi был примером =]

так, чтобы ответить на правильный вопрос, да, вы можете. Тип в ActiveX, наиболее близкий к NPObject, - IDispatch (или IDispatchEx ). Вместо того, чтобы иметь GetProperty, SetProperty и Invoke, вы просто вызываете Invoke и сообщаете ему, должно ли оно получить свойство, установить свойство или вызвать метод. Сначала вам нужно выполнить запрос, чтобы получить DISPID участника; подобно NPIdentifier, DISPID - это отображение между строкой и числом.

Если вы еще не видели его, вам стоит взглянуть на FireBreath , который предоставляет абстракцию, позволяющую вам написать плагин, который работает как с NPAPI, так и с ActiveX с одной и той же кодовой базой. Он имеет оболочку , позволяющую ему использовать объекты IDispatch , которые вы, вероятно, найдете полезными в качестве примера.

Короче говоря, вы можете использовать объекты JS практически так же, как и с NPObject, используя IDispatch (или даже лучше, IDispatchEx). Большинство вещей из javascript поступают как IDispatchEx, но иногда я видел случаи, когда требовалась поддержка отработки отказа IDispatch.

Надеюсь, это поможет, и я надеюсь, что мой первоначальный ответ (прежде чем я перечитал ваш вопрос) не отбросил вас.

...