Create MultiDimensional javascript array from C++ -


edit: have figured out problem. there several bugs in posted code came (very) poor understanding of com, notably not understanding calls getdispid doing. i'll update post correctly working code, in case else runs issue.


i have c++ application (mfc) embedded web browser. calling c++ functions javascript using:

var arrresult = window.external.myfunction (myargs); 

it works well. send data array using code codeproject article http://www.codeproject.com/articles/88753/creating-javascript-arrays-and-other-objects-from

now need send 2-dimensional array. code works me, now. note that, in javascript, 2 dimensional array comes object, not array. so, isarray returns false:

omyresult = window.external.vpquery (strquery); if (array.isarray (omyresult))     alert ("this array!"); 

but successful:

if( (typeof arrvpresult === "object") && (arrvpresult !== null) )     alert ("this object!"); 

so can iterate through this:

    (var strprop in arrvpresult) {         if (arrvpresult.hasownproperty (strprop)) {               //  something...         }     } 

edit #2: if call theobject->getdispid uses numeric value rather text value (where ccombstr(rarrdata[n]) way down below) created object act array in javascript (and have .length value). if use text value, act object (and not have .length value).

anyway, here's c++ code. hope it's useful someone.

bool cmyhtmldispatch::buildjsarraytest  (cstringarray& rarrdata, variant& vtresult) {     ccomqiptr<idispatchex>  theobject;     dispid                  didmainarray    = 0;     dispid                  didcursubarray  = 0;     dispid                  didtemp         = 0;      //     //  first create our main array.  elements in array      //  arrays, too, giving our 2 dimensional array.  we'll operate on     //  array using theobject.  far can tell, don't need didmainarray (the dispatch id)      if (! buildjsarray_createobject (vtresult, theobject, didmainarray))         return false;      if (null == theobject)         return false;      //     // create our sub-arrays.  each of them contain array of strings.      cstring strindex;     for(size_t n = 0; n < rarrdata.getcount(); n++)     {         ccomqiptr<idispatchex>  theobjectsubarray;         _variant_t              vtsubarray;          //         //  above, creates our javascript array object.  we'll refer         //  using theobjectsubarray.  won't need use didcursubarray (the dispatch id)          if (! buildjsarray_createobject (vtsubarray, theobjectsubarray, didcursubarray))             return false;          //         //  add our data sub-array, we'll add sub-array main array         //  in our case, we'll create test data.  we'll use value in rarrdata          //  key name , fill sub-array values variations on key name.          (int x = 0; x < 3; x ++) {             //             //  first create key our index in our sub array.  we'll use index             //  number key, though have pass getdispid string.             //  fdexnameensure makes theobjectsubarray create us.  sends dispatch id              //  we'll use below set value our key in invokeex              strindex.format (_t("%d"), x);             if (failed (theobjectsubarray->getdispid (ccombstr(strindex), fdexnameensure, &didtemp)))                 break;              //             //  add our sub-item value string sub-array object.   we'll call             //  invokeex on thesubobjectarray , need pass in didtemp knows             //  key we're setting value for.                cstring s; s.format (_t("%s - %d"), rarrdata[n], x);             ccomvariant varg (s);              dispid      namedargs[] = {dispid_propertyput};             dispparams  p           = {&varg, namedargs, 1, 1};              if (failed (theobjectsubarray->invokeex(didtemp, locale_user_default, dispatch_propertyput, &p, null, null, null)))                 return false;         }          //         //  ok!  now, in theory, data rarrdata[n] in didcursubarray.  let's         //  add main array.  remember getdispid returns dispatch id         //  we'll use in our call invokeex.          if (failed (theobject->getdispid (ccombstr(rarrdata[n]), fdexnameensure, &didtemp)))             break;          ccomvariant varg (vtsubarray);          dispid      namedargs[] = {dispid_propertyput};         dispparams  p           = {&varg, namedargs, 1, 1};          //         //  because our varg contains idispatch, have use dispatch_propertyputref          //  rather dispatch_propertyput.  here we're associating sub array         //  key dispatch id didtemp.          if (failed (theobject->invokeex (didtemp, locale_user_default, dispatch_propertyputref, &p, null, null, null))) // dispatch_propertyput             return false;      } // end loop through main data      return true; } // end build js array int      ////////////////////////////////////////////////////////////////////////////// // //  grunt work // //  function turns our mfc array native javascript array.   //  javascript can't handle safearrays directly.  _can_ handle them  //  using javascript object vbarray, this: //  var arrresult = new vbarray(window.external.cb_customfunctionwithparams (ored, npi)).toarray() // //  doing buildjsarray stuff lets javascript side //  treat native javascript array. // //  got code from: //  http://www.codeproject.com/articles/88753/creating-javascript-arrays-and-other-objects-from // bool cmyhtmldispatch::buildjsarray_createobject (variant& vtresult, ccomqiptr<idispatchex>& rpobject, dispid& did) {     if (null == m_phtmlview)         return false;      cwebdocument2ptr    pwebdocument2 = m_phtmlview->getwebdocument2 ();     if (null == pwebdocument2)         return false;      ccomqiptr<idispatch> scriptdispatch;     pwebdocument2->get_script (&scriptdispatch);      if (!scriptdispatch)         return false;      //     // dispid "array"      did = 0;     lpolestr lpnames[] = {l"array"};     hresult hr = scriptdispatch->getidsofnames(iid_null, lpnames, 1, locale_user_default, &did);     if (failed(hr))         return false;      //     // invoke scriptdispatch dispatch_propertyget "array"      ccomvariant vtret;     dispparams params = {0};     hr = scriptdispatch->invoke(did, iid_null, locale_user_default, dispatch_propertyget, &params, &vtresult, null, null);     if (failed(hr))         return false;      //     // check result: should vt_dispatch      if ((vt_dispatch != vtresult.vt) || (null == vtresult.pdispval))         return false;      //     // idispatchex on returned idispatch      ccomqiptr<idispatchex> prototype(vtresult.pdispval);     if (!prototype)         return false;      //     // call invokeex dispid_value     // , dispatch_construct construct new array      variantclear (&vtresult);     hr = prototype->invokeex(dispid_value, locale_user_default, dispatch_construct, &params, &vtresult, null, null);     if (failed(hr))         return false;      //     // vtresult should contain new array now.      if ((vt_dispatch != vtresult.vt) || (null == vtresult.pdispval))         return false;      //     // idispatchex on returned idispatch      ccomqiptr<idispatchex> theobject(vtresult.pdispval);     if (!theobject)         return false;      rpobject = theobject;     return true; } 


Comments

Popular posts from this blog

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

c++ - OpenMP unpredictable overhead -

javascript - Wordpress slider, not displayed 100% width -