문제

I have found Passing an array from Javascript to C++ solution, but I have another task: Passing an object from Javascript to C++ (if I use IWebBrowser2 with IDispatch)

I mean that I need call C++ method via window.external.method with JavaScript object argument

var obj = {name: "Petr", group: "Friend"};
window.external.myMethod(obj);

How to get access to object member "name", "group", etc. ?

도움이 되었습니까?

해결책

You can access the object's properties via the IDispatch interface and its methods GetIDsOfNames and Invoke.

Depending on your definition of myMethod, you should be receiving obj as either a VARIANT or an IDispatch * in your C++ code. If a VARIANT, vt should be VT_DISPACTH, in which case you can safely dereference pdispval.

Once you have an IDispatch pointer, you can use GetIDsOfNames to get the DISPID for a property that you're interested in like so:

_bstr_t sPropertyName = L"myProperty";
DISPID dispid = 0;
HRESULT hr = pDispatch->GetIDsOfNames(IID_NULL, &sPropertyName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
if(SUCCEEDED(hr))
{
    ...

Once you have successfully received your DISPID, you must call Invoke differently according to whether you would like to get a value, set a value or call a method.

For instance, to get a value:

    VARIANT vValue;
    hr = pDispatch->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, 0, &vValue, 0, 0);
    if(SUCCEEDED(hr))
    {
        ...

See the documentation for Invoke for more information about the different permutations when calling it.

다른 팁

If you just need to be able to read the object fields, the most flexible way is to use JSON.

On your web page side use:

var obj = {name: "Petr", group: "Friend"}; window.external.myMethod(JSON.stringify(obj));

On your C++ side define myMethod() to accept a single string argument. Then use a C++ JSON parser to parse this argument into a readable object.

static HRESULT \
IDispatch_VarGet (IDispatch *pRDisp, LPOLESTR Name, VARIANT *pVarRes)
{
    DISPPARAMS DispParams;
    DISPID dispid;
    HRESULT hr;

    if ((hr = IDispatch_GetIDsOfNames (pRDisp, &IID_NULL,
                &Name, 1, LOCALE_SYSTEM_DEFAULT, &dispid)))
        return hr;

    ZeroMemory (&DispParams, sizeof (DispParams));

    hr = IDispatch_Invoke (pRDisp, dispid, &IID_NULL,
            LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET,
            &DispParams, pVarRes, NULL, NULL);

    return hr;
}


static HRESULT \
IDispatch_VarPut (IDispatch *pRDisp, LPOLESTR Name, VARIANT *pVarArg)
{
    DISPPARAMS DispParams;
    DISPID dispid, ndispid;
    HRESULT hr;

    if ((hr = IDispatch_GetIDsOfNames (pRDisp, &IID_NULL,
                &Name, 1, LOCALE_SYSTEM_DEFAULT, &dispid)))
        return hr;

    ndispid = DISPID_PROPERTYPUT;

    DispParams.rgvarg = pVarArg;
    DispParams.rgdispidNamedArgs = &ndispid;
    DispParams.cArgs  = 1;
    DispParams.cNamedArgs = 1;

    hr = IDispatch_Invoke (pRDisp, dispid, &IID_NULL,
            LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT,
            &DispParams, NULL, NULL, NULL);

    return hr;
}


static HRESULT \
IDispatch_StrPut (IDispatch *pRDisp, LPOLESTR Name, LPOLESTR StrVal)
{
    VARIANT varg;
    HRESULT hr;

    VariantInit (&varg);

    V_VT   (&varg) = VT_BSTR;
    V_BSTR (&varg) = SysAllocString (StrVal);

    hr = IDispatch_VarPut (pRDisp, Name, &varg);

    VariantClear (&varg);

    return hr;
}


static HRESULT \
IDispatch_IntPut (IDispatch *pRDisp, LPOLESTR Name, int IntVal)
{
    VARIANT varg;
    HRESULT hr;

    VariantInit (&varg);

    V_VT (&varg) = VT_I4;
    V_I4 (&varg) = IntVal;

    hr = IDispatch_VarPut (pRDisp, Name, &varg);

    VariantClear (&varg);

    return hr;
}

...

if ((hr = IDispatch_StrPut (pRDisp, L"code", buff)))
    return hr;

if ((hr = IDispatch_IntPut (pRDisp, L"state", state)))
    return hr;

...

{
    // ...
    VariantInit (&varg);

    if ((hr = IDispatch_VarGet (pRDisp, L"code", &varg)))
    {
        VariantClear (&varg);
        return hr;
    }

    if (V_VT (&varg) == VT_BSTR)

    // ...

    VariantClear (&varg);
    return hr;
}

and jave code sample...

var frec = {code:'', state:0};

frec.code = row.cells[0].innerHTML;
external.FeatureStateChg (frec);
_featState (row.cells[2], frec.state);

...

var frec = {code:'', name:'', state:0};

if (!external.FeaturesEnum (frec, i))
    break;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top