1. Call JavaScript Functions in COM components
// Connection point method page Javascript script
<Object classid = "CLSID: B568F111-DFE4-4944-B67F-0728AB2AB30F" id = "testcom" viewastext> </Object>
<Script language = "JavaScript" for = "testcom" event = "state (s)">
Alert ("state (" + S + ")");
Return 123;
</SCRIPT>
<Script language = "JavaScript">
Testcom. firestateevent ("hello ");
</SCRIPT>
// Event property method page Javascript script
Function onstate (s ){
Alert ("onstate (" + S + ")");
Return 456;
}
VaR o = new activexobject ("testatl. testcom ");
O. onstate = onstate;
O. firestateevent ("hello ");
// COM component vc7.1 ATLCode
_ Interface _ itestcomevents {
[ID (1), helpstring ("state event")] hresult state ([in] BSTR Str );
};
_ Event _ interface _ itestcomevents;
Idispatchptr m_onstate; // event attributes
Stdmethod (get_onstate) (idispatch ** pval ){
* Pval = m_onstate;
Return s_ OK;
};
Stdmethod (put_onstate) (idispatch * newval ){
M_onstate = newval;
Return s_ OK;
};
Stdmethod (firestateevent) (BSTR Str ){
_ Raise State (STR); // triggers a connection point event
Ccomvariant result;
Ccomvariant avarparams [1] = {STR };
Dispparams = {avarparams, null, 1, 0 };
Raise info raise Info;
Memset (& Parameter info, 0, sizeof parameter info );
Uint nargerr = (uint)-1; // initialize to invalid ARG
If (m_onstate) // triggers a property event
Hresult hR = m_onstate-> invoke (0, iid_null, locale_user_default,
Dispatch_method, & dispparams, & result, & policinfo, & nargerr );
Return s_ OK;
}
See:
How to call a script function from a VC webbrowser Application
How to use JavaScript function object in COM object?
Call JavaScript Functions in COM components
2. Transfer the structure array from the page JavaScript to the COM Component
// Page script
VaR o = new activexobject ("testatl. testcom ");
O. onstate = onstate;
O. Put ("array", {0: 123, 1: "ABC "});
O. Put ("array", [456, "def"]);
O. Put ("array", [{name: "Tom", age: 8 },{ name: "Jack", age: 10}]);
VaR A = new array (789, "Ghi"); // has "length" Property
O. Put ("array", );
// COM component vc7.1 ATL code
Stdmethodimp ctestcom: Put (BSTR key, variant value)
{
Wchar output [4096] = l "";
If (0 = wcsicmp (Key, l "array") & vt_dispatch = value. Vt)
{
Idispatchptr spdisp = value. pdispval;
Dispid = 0;
Dispparams = {null, null, 0, 0 };
Ccomvariant result;
Raise info raise Info;
Memset (& Parameter info, 0, sizeof parameter info );
Uint nargerr = (uint)-1; // initialize to invalid ARG
Unsigned int length = 0; // array length or number of attributes
Lpolestr func = l "length ";
Hresult hR = spdisp-> getidsofnames (guid_null, & func, 1, locale_system_default, & dispid );
If (s_ OK = HR) {// if the "length" attribute exists
HR = spdisp-> invoke (dispid, iid_null, locale_user_default, dispatch_propertyget, & dispparams, & result, & policinfo, & nargerr );
If (s_ OK = HR & vt_i4 = result. Vt)
Length = result. intval; // directly read the array Length
} Else {
Unsigned int ntypeinfo = 0;
HR = spdisp-> gettypeinfocount (& ntypeinfo );
Atlassert (1 = ntypeinfo );
Itypeinfoptr sptypeinfo;
HR = spdisp-> gettypeinfo (0, 0, & sptypeinfo );
Typeattr * ptypeattr = NULL;
HR = sptypeinfo-> gettypeattr (& ptypeattr );
// Atlassert ("{C59C6B12-F6C1-11CF-8835-00A0C911E8B2}" = ptypeattr-> guid); // JScript:
Length = ptypeattr-> cvars; // read the array length from the type information
Sptypeinfo-> releasetypeattr (ptypeattr );
}
For (unsigned int I = 0; I <length; I ++)
{
Wchar Buf [32];
_ Itow (I, Buf, 10 );
Func = Buf;
HR = spdisp-> getidsofnames (guid_null, & func, 1, locale_system_default, & dispid );
HR = spdisp-> invoke (dispid, iid_null, locale_user_default, dispatch_propertyget, & dispparams, & result, & policinfo, & nargerr );
If (s_ OK! = HR)
Continue;
If (vt_dispatch = result. Vt ){
Idispatchptr spitem = result. pdispval;
Func = l "name ";
HR = spitem-> getidsofnames (guid_null, & func, 1, locale_system_default, & dispid );
HR = spitem-> invoke (dispid, iid_null, locale_user_default, dispatch_propertyget, & dispparams, & result, & policinfo, & nargerr );
If (s_ OK = HR & vt_bstr = result. Vt)
Swprintf (output + wcslen (output), L "name = % s", result. bstrval );
Func = l "Age ";
HR = spitem-> getidsofnames (guid_null, & func, 1, locale_system_default, & dispid );
HR = spitem-> invoke (dispid, iid_null, locale_user_default, dispatch_propertyget, & dispparams, & result, & policinfo, & nargerr );
If (s_ OK = HR & vt_i4 = result. Vt)
Swprintf (output + wcslen (output), L "age = % d/N", result. intval );
} Else if (vt_bstr = result. Vt)
Swprintf (output + wcslen (output), L "BSTR: % s/n", result. bstrval );
Else if (vt_i4 = result. Vt)
Swprintf (output + wcslen (output), L "I4: % d/N", result. intval );
Else
Swprintf (output + wcslen (output), L "item. Vt = % d/N", result. Vt );
}
}
Firestateevent (output );
Return s_ OK;
}
3. enumerate the content of the IE window and call the script
# Import <mshtml. TLB> // Internet Explorer 5
# Import <shdocvw. dll>
Shdocvw: ishellwindowsptr spshwinds;
Spshwinds. createinstance (_ uuidof (shdocvw: shellwindows ));
Long ncount = spshwinds-> getcount ();
Idispatchptr spdisp;
For (long I = 0; I <ncount; I ++)
{
_ Variant_t VA (I, vt_i4 );
Spdisp = spshwinds-> item (VA );
Shdocvw: iwebbrowser2ptr spbrowser (spdisp );
If (spbrowser! = NULL)
{
_ Bstr_t location = spbrowser-> getlocationname ();
If (_ bstr_t (L "test dapctrl") = Location) // find the specified ie window
{
Ihtmldocument2ptr spdoc (spbrowser-> getdocument ());
If (spdoc! = NULL)
{
_ Bstr_t exp = m_onstate;
Idispatch * PDIS = NULL;
HR = spdoc-> get_script (& PDIS );
If (PDIS ){
Dispid tmpdispid = 0;
Lpolestr func = l "test"; // JavaScript function name
HR = PDIS-> getidsofnames (guid_null, & func, 1, locale_system_default, & tmpdispid );
If (s_ OK = HR)
HR = PDIS-> invoke (tmpdispid, iid_null, locale_user_default,
Dispatch_method, & dispparams, & result, & policinfo, & nargerr );
}
}
}
}
}
See:
Howto: connect to a running instance of Internet Explorer
Interaction between ActiveX components and JavaScript
ActiveX components control their IE Windows
4. Execute the script in VC
# Import <msscript. ocx> // msscript. ocx
Using namespace msscriptcontrol;
Iscriptcontrolptr pscriptcontrol (_ uuidof (scriptcontrol ));
Lpsafearray PSA;
Safearraybound rgsabound [] = {1, 0}; // 1 elements, 0-based
Int I;
PSA = safearraycreate (vt_variant, 1, rgsabound );
If (! PSA)
{
Return e_outofmemory;
}
Variant vflavors [1];
For (I = 0; I <1; I ++)
{
Variantinit (& vflavors [I]);
V_vt (& vflavors [I]) = vt_bstr;
}
V_bstr (& vflavors [0]) = sysallocstring (BSTR );
Long lzero = 0;
HR = safearrayputelement (PSA, & lzero, & vflavors [0]);
For (I = 0; I <1; I ++)
{
Sysfreestring (vflavors [I]. bstrval );
}
Pscriptcontrol-> Language = "jscript ";
Pscriptcontrol-> allowui = true;
_ Bstr_t exp = l "1 + 2 + 3 ";
_ Variant_t outpar = pscriptcontrol-> eval (exp );
// _ Variant_t outpar = pscriptcontrol-> executestatement (exp );
// _ Variant_t outpar = pscriptcontrol-> Run ("mystringfunction", & PSA );
_ Bstr_t bstrreturn = (_ bstr_t) outpar;
Char * presult = (char *) bstrreturn;
Safearraydestroy (PSA );
See:
How to call run () method of the Microsoft Script control in C ++