C++ 与 javaSript 的相互调用
[C++ 调用 javascript][javascript 调用 C++]
C++ 调用 javascript
相关函数与结构:
- 函数
- 结构体:
- VARIANT(用于传递参数)
方法一(不在乎 js 函数的返回值):
IHTMLDocument2* pDocument; IHTMLWindow2* pWindow; //获得 html 的 Document 节点 HRESULT hr = GetDHtmlDocument(&pDocument); //获得 Document 的窗口节点 pDocument->get_parentWindow(&pWindow); VARIANT ret; ret.vt = VT_EMPTY; pWindow->execScript(AllocSysString("jsfunc()"),L"JavaScript",&ret); //清理工作,释放 Document 和 window节点 pDocument->Release(); pWindow->Release();
方法二(需要获得 js 函数的返回值):
IHTMLDocument2* pDocument; IHTMLWindow2* pWindow; DISPPARAMS dispparams;//用于给 JS 传递参数对象 DISPID dispid; EXCEPINFO excepInfo;//获取JS中异常的对象 CComVariant vaResult;//JS返回的结果值对象 //获得 html 的 Document 节点及 Document 对应的窗口节点 GetDHtmlDocument(&pDocument); pDocument->get_parentWindow(&pWindow); //初始化JS所用的参数对象,JS中异常的对象 memset(&dispparams, 0, sizeof dispparams); memset(&excepInfo, 0, sizeof excepInfo); //设置参数个数,并开辟参数空间 dispparams.cArgs=2; dispparams.rgvarg = new VARIANT[dispparams.cArgs]; //设置每个参数的类型 dispparams.rgvarg[0].vt = VT_BSTR; dispparams.rgvarg[1].vt = VT_BSTR; //为参数赋值 CComBSTR fromMFC1=_T("one"); CComBSTR fromMFC2=_T("two"); fromMFC2.CopyTo(&dispparams.rgvarg[1].bstrVal); fromMFC1.CopyTo(&dispparams.rgvarg[0].bstrVal); UINT nArgErr = (UINT)-1; CComBSTR szMember = _T("CalledJs"); pWindow->GetIDsOfNames(IID_NULL, &szMember,1,LOCALE_SYSTEM_DEFAULT,&dispid); pWindow->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo,&nArgErr); //显示 JS 返回的结果 CString str(vaResult.bstrVal); this->MessageBox(str); //清理工作,释放 Document 和 window 节点 pDocument->Release(); pWindow->Release();
javascript 调用 C++
相关函数及宏链接到 MSDN:
- EnableAutomation
- SetExternalDispatch
- DECLARE_DISPATCH_MAP
- BEGIN_DISPATCH_MAP
- DISP_FUNCTION
- END_DISPATCH_MAP
步骤:
- 让 CTestHtmlDialog 支持自动化,即在 OnInitDialog() 中添加
EnableAutomation();
- 将自身暴露给 Javascript ,即在 OnInitDialog() 中添加
SetExternalDispatch(GetIDispatch(TRUE)); //将浏览器控件的扩展接口设置为对话框自身的 IDispatch
- 声明 DISPATCH_MAP,即在 TestHtmlDialog.h 中声明对应映射
DECLARE_DISPATCH_MAP()
- 定义对应的 C++ 函数,用于给 Javascript 调用
void func() { MessageBox(L"hello!"); }
- 定义DISPATCH_MAP,和添加对应函数映射,即在 TestHtmlDialog.cpp 中
BEGIN_DISPATCH_MAP(CMyDHtmlDialog, CDHtmlDialog) DISP_FUNCTION(CMyDHTMLDialog, "SayHello", func, VT_EMPTY, VTS_NONE) END_DISPATCH_MAP()
- 取消JS在调用 C++ 时的提醒框,即在 CTestHtmlDialog 中,重载 CanAccessExternal() 函数
BOOL CWebbrowserDlg::CanAccessExternal() { return TRUE; }
- 在 Javascript 中调用 C++ 函数
function Button1_onclick() { //调用 C++ 的 func,函数 external.SayHello(); }