转自:http://blog.csdn.net/sunflover454/article/details/60873557(侵删)
C++和js相互调用是个有意思的事情。
一、js中调用C++函数。函数原型
- int g_FunSub(int x,int y);
调用方式如下:
- <html>
- <head>
- <meta charset="utf-8" />
- <title></title>
- <script language="javascript">
- function CallCppFunSub(x,y)
- {
- var num = window.external.g_FunSub(x,y);
- alert(num);
- return num
- }
- function JsFunSub(x,y)
- {
- var num = x - y;
- alert(num);
- return num
- }
- </script>
- </head>
- <body>
- <button type="button" onclick="CallCppFunSub(4,7)">调用C++函数</button>
- </body>
- </html>
- #pragma once
- class CWebBrowserExUI :
- public CWebBrowserUI
- {
- public:
- CWebBrowserExUI();
- ~CWebBrowserExUI();
- LPCTSTR GetClass() const;
- LPVOID GetInterface(LPCTSTR pstrName);
- virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(__RPC__in REFIID riid, __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames, UINT cNames, LCID lcid, __RPC__out_ecount_full(cNames) DISPID *rgDispId);
- virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
- virtual HRESULT STDMETHODCALLTYPE GetExternal(IDispatch **ppDispatch)
- {
- //重写GetExternal返回一个ClientCall对象
- *ppDispatch = this;
- return S_OK;
- }
- };
- #include "stdafx.h"
- #include "WebBrowserExUI.h"
- #include <atlcomcli.h>
- int g_FunSub(int x, int y)
- {
- return (x - y);
- }
- CWebBrowserExUI::CWebBrowserExUI()
- {
- }
- CWebBrowserExUI::~CWebBrowserExUI()
- {
- }
- LPCTSTR CWebBrowserExUI::GetClass() const
- {
- return _T("WebBrowserExUI");
- }
- LPVOID CWebBrowserExUI::GetInterface(LPCTSTR pstrName)
- {
- if (_tcsicmp(pstrName, _T("WebBrowserEx")) == 0)
- return static_cast<CWebBrowserExUI*>(this);
- return CActiveXUI::GetInterface(pstrName);
- }
- HRESULT CWebBrowserExUI::GetIDsOfNames(const IID& riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
- {
- //DISP ID 从200开始
- if (_tcscmp(rgszNames[0], _T("g_FunSub")) == 0)
- *rgDispId = 500;
- return S_OK;
- }
- HRESULT CWebBrowserExUI::Invoke(DISPID dispIdMember, const IID& riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
- {
- //MyOutputDebugStringW(L"%d\n", dispIdMember);
- switch (dispIdMember)
- {
- case 500:
- {
- // 注意参数顺序,反向
- VARIANTARG *varArg = pDispParams->rgvarg;
- int x = _ttoi(static_cast<_bstr_t>(varArg[1]));
- int y = _ttoi(static_cast<_bstr_t>(varArg[0]));
- int n = g_FunSub(x, y);
- *pVarResult = CComVariant(n);
- return S_OK;
- }
- default:
- break;
- }
- return CWebBrowserUI::Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
- }
- function JsFunSub(x,y)
- void CMainFrameWnd::OnClick(TNotifyUI& msg)
- {
- CDuiString sCtrlName = msg.pSender->GetName();
- if (sCtrlName.CompareNoCase(_T("CallJsBtn")) == 0)
- {
- // C++调用js方法,示例
- // 注意参数顺序,反向
- VARIANT arg[2] = { CComVariant(7),CComVariant(3)};//JsFunSub(3,7)
- VARIANT varRet;
- m_pBrowser->InvokeMethod(m_pBrowser->GetHtmlWindow(),_T("JsFunSub"),&varRet,arg,2);
- int nResult = varRet.intVal;//-4
- return;
- }
- WindowImplBase::OnClick(msg);
- }
js中这样实现:
- <html>
- <head>
- <meta charset="utf-8" />
- <title></title>
- <script language="javascript">
- function CallCppFunSub(x,y)
- {
- var num = window.external.g_FunSub(x,y);
- alert(num);
- return num
- }
- function JsFunSub(x,y)
- {
- var num = x - y;
- alert(num);
- return num
- }
- </script>
- </head>
- <body>
- <button type="button" onclick="CallCppFunSub(4,7)">调用C++函数</button>
- </body>
- </html>
执行js务必在网页加载完成时执行,示例代码片段如下:
- void CMyWebBrowserEvenrHandler::NavigateComplete2(CWebBrowserUI* pWeb, IDispatch* pDisp, VARIANT*& url)
- {
- // 页面加载完毕才能执行js
- // execute js start
- IDispatch *pHtmlDocDisp = pWeb->GetHtmlWindow();
- IHTMLDocument2 *pHtmlDoc2 = NULL;
- HRESULT hr = pHtmlDocDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc2);
- pHtmlDocDisp->Release();
- if (SUCCEEDED(hr) && pHtmlDoc2 != NULL)
- {
- CComQIPtr<IHTMLWindow2> pHTMLWnd;
- pHtmlDoc2->get_parentWindow(&pHTMLWnd);
- if (SUCCEEDED(hr) && pHTMLWnd != NULL)
- {
- //CComBSTR bstrjs = SysAllocString(_T("document.documentElement.style.overflow = 'hidden'"));//去除水平方向滚动条
- CComBSTR bstrjs = SysAllocString(_T("document.documentElement.style.overflowY = 'hidden'"));//去除竖直方向滚动条
- CComBSTR bstrlan = SysAllocString(_T("javascript"));
- VARIANT varRet;
- pHTMLWnd->execScript(bstrjs, bstrlan, &varRet);
- }
- }
- // execute js end
- }