这里有一篇很好的文章,介绍了如何使用C++来实现此功能。
点击这里查看。
接下来是我的解释。假设您的客户端JavaScript代码如下:
function myMethod(name)
{
alert("Hello " + name);
return "Got it!";
}
你可以这样称呼它:
CStringArray arrArgs;
arrArgs.Add(L"John Smith");
CComVariant varRes;
if(CallClientScript(L"myMethod", &arrArgs, &varRes))
{
if(varRes.vt == VT_BSTR)
AfxMessageBox(varRes.bstrVal);
}
实际与 IHTMLWindow2
进行接口的函数如下:
BOOL CallClientScript(LPCTSTR pStrFuncName, CStringArray* pArrFuncArgs, CComVariant* pOutVarRes)
{
BOOL bRes = FALSE;
CComVariant vaResult;
CComPtr<IHTMLDocument2> pIDoc2;
if(SUCCEEDED(this->GetDHtmlDocument(&pIDoc2)))
{
CComPtr<IDispatch> spScript;
if(SUCCEEDED(pIDoc2->get_Script(&spScript)))
{
CComBSTR bstrMember(pStrFuncName);
DISPID dispid = NULL;
if(SUCCEEDED(spScript->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_USER_DEFAULT, &dispid)))
{
const int arraySize = pArrFuncArgs ? pArrFuncArgs->GetSize() : 0;
DISPPARAMS dispparams;
memset(&dispparams, 0, sizeof dispparams);
dispparams.cArgs = arraySize;
dispparams.rgvarg = new VARIANT[dispparams.cArgs];
dispparams.cNamedArgs = 0;
for( int i = 0; i < arraySize; i++)
{
CComBSTR bstr = pArrFuncArgs->GetAt(arraySize - 1 - i);
bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
dispparams.rgvarg[i].vt = VT_BSTR;
}
EXCEPINFO excepInfo;
memset(&excepInfo, 0, sizeof excepInfo);
UINT nArgErr = (UINT)-1;
if(SUCCEEDED(spScript->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo, &nArgErr)))
{
bRes = TRUE;
}
delete [] dispparams.rgvarg;
}
}
}
if(pOutVarRes)
*pOutVarRes = vaResult;
return bRes;
}