C++调JavaScript的几种方法:
方法一:当IE的文档模式为IE9及以上时不生效
HRESULT hr = E_FAIL; CComPtr<IDispatch> spDisp; hr = m_spWebBrower->get_Document(&spDisp); if (!SUCCEEDED(hr) || !spDisp) return; m_spDoc2 = spDisp; if (!m_spDoc2) return; CComPtr<IHTMLWindow2> spWin; hr = m_spDoc2->get_parentWindow(&spWin); CComDispatchDriver disp = spWin; CComVariant result; disp.Invoke1(L"eval", &CComVariant("testCallJavascript()"), &result);
方法二:该方法的弊端是execScript的返回值始终都是VM_EMPTY,我们无法知道函数执行的返回值
CComPtr<IDispatch> spScript; hr = m_spDoc2->get_Script(&spScript); if (!SUCCEEDED(hr) || !spScript) return FALSE; CComPtr<IHTMLWindow2> m_sphtmlWnd = spScript; CComBSTR bstrMember(L"testCallJavascript()"); CComBSTR bstrlan = SysAllocString(L"javascript"); VARIANT varRet; hr = E_FAIL; hr = m_sphtmlWnd->execScript(bstrMember, bstrlan, &varRet);
方法三:同上
CComPtr<IDispatch> spScript; hr = m_spDoc2->get_Script(&spScript); if (!SUCCEEDED(hr) || !spScript) return FALSE; CComPtr<IHTMLWindow2> spWin; hr = m_spDoc2->get_parentWindow(&spWin); CComQIPtr<IDispatchEx> spWndEx = spWin; CComBSTR bstrMember(_T("testCallJavascript")); DISPID dispid = NULL; hr = spWndEx->GetDispID(bstrMember, fdexNameCaseInsensitive, &dispid); if (!SUCCEEDED(hr)) return FALSE; hr = spWndEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &vaResult, NULL, NULL);
那么,今天我来补充一下如何解决在IE11不生效的问题
HRESULT hr = E_FAIL; CComPtr<IHTMLWindow2> spParentWin; hr = m_spDoc2->get_parentWindow(&spParentWin); if (!SUCCEEDED(hr) || !spParentWin) return FALSE; CComBSTR bstrlan = L"javascript"; VARIANT varRet; hr = E_FAIL; hr = spParentWin->execScript(bstrJavaScript, bstrlan, &varRet); if (!SUCCEEDED(hr)) return FALSE;
其中,bstrJavaScript表示要执行的完整.js文件中的代码,这种方法与方法二唯一的区别是方法二的参数是JS函数,而该方法的execScript第一个参数是完整的JS代码
同理,如果你不愿意Load JS源文件,bstrJavaScript 变量还可以是如下字符串
scriptEle=document.createElement('script'); scriptEle.setAttribute('src','xxx.js'); scriptEle.setAttribute('id',''); scriptEle.defer=true; document.body.appendChild(scriptEle);