Reputation: 4364
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. ?
Upvotes: 3
Views: 4350
Reputation: 19
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;
Upvotes: 0
Reputation: 4913
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.
Upvotes: 2
Reputation: 6424
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.
Upvotes: 0