To to do this, you do however need a JSContext, and which one you want depends on what you're doing. If you want the code to run as if it was executed by the document that's loaded into the window in question, then you need to get the JSContext from that document, or window, rather. This could be done using a combination of the JS context iterator (JS_ContextIterator()) and XPConnect, but it gets a bit tricky and doesn't scale all that well, so the alternative is to use frozen interfaces. If you have a pointer to the window, you can QI that to nsIScriptGlobalObject and call GetContext() on that, and you'll get an nsIScriptContext. On that, you can call GetNativeContext() and you'll get the JSContext for that window (as a void*, so you'll need to cast it to a JSContext). From there, you can use the JS engine API to compile and execute your script. If you do end up using nsIScriptContext, you're already using internal interfaces (which we make no guarantees about, they may, and probably will, change, from version to version) you can use the methods in that interface to execute your script as well.
I hope this gets you started!
Tom Lee wrote:
Hi ,
I read a couple articles regarding the calling of java script functionality from C++., and I was wondering if anybody could possible help me out .
I have an XUL toolbar (Netscape 7.x) that calls an XPCom component ( C++). I need to be able to call a JavaScript function that may or may not be present within the document - from my XPCOM component. I have tried several ways, but I cannot seem to get the JavaScript within the document. I have done this with a plug-in for IE and it works like a charm. The way I do it in IE is listed below. I have tried several different ways to try to get the java script and have failed:( I would greatly appreciate some insight to this. Am I making this too complicated? Any help you could offer I would greatly appreciate.
Thank you very much,
...
CComQIPtr<IWebBrowser2> spBrowser(pDispatch);
VARIANT_BOOL b = VARIANT_FALSE; spBrowser->get_TopLevelContainer(&b);
CComPtr<IDispatch> pDisp; spBrowser->get_Document(&pDisp);
CComQIPtr<IHTMLDocument2> spDoc(pDisp);
// GetDomain(pDisp); CComPtr<IDispatch> pScriptDisp; HRESULT hr = spDoc->get_Script(&pScriptDisp);
if(pScriptDisp) { _bstr_t btMember(JSCRIPT_FUNCTION); DISPID dispid = NULL;
BSTR bstrFunction = btMember.copy();
hr = pScriptDisp->GetIDsOfNames(IID_NULL,&bstrFunction,1, LOCALE_SYSTEM_DEFAULT,&dispid);
// Check to see if function exists if(FAILED(hr)) return;
int arraySize = 0; DISPPARAMS dispparams; ZeroMemory(&dispparams, sizeof(DISPPARAMS)); dispparams.cArgs = arraySize; dispparams.rgvarg = new VARIANT[dispparams.cArgs];
for( int i = 0; i < arraySize; i++) { // CComBSTR bstr = paramArray.GetAt(arraySize - 1 - i); // back reading // bstr.CopyTo(&dispparams.rgvarg[i].bstrVal); // dispparams.rgvarg[i].vt = VT_BSTR; } dispparams.cNamedArgs = 0;
EXCEPINFO excepInfo; ZeroMemory(&excepInfo, sizeof(EXCEPINFO)); CComVariant vaResult; UINT nArgErr = (UINT)-1; // initialize to invalid arg
hr = pScriptDisp->Invoke(dispid,IID_NULL,0, DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo,&nArgErr);
delete [] dispparams.rgvarg;
if(SUCCEEDED(hr) && SUCCEEDED(excepInfo.scode)) { _bstr_t b(vaResult.bstrVal, true);
