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);