duilib CWebBrowser控件 cxx与js交互

时间:2022-09-22 09:07:26

转自:http://blog.csdn.net/sunflover454/article/details/60873557(侵删)

C++和js相互调用是个有意思的事情。

一、js中调用C++函数。函数原型

[html]  view plain  copy
  1. int g_FunSub(int x,int y);  

调用方式如下:

[html]  view plain  copy
  1. <html>    
  2. <head>    
  3.     <meta charset="utf-8" />    
  4.     <title></title>    
  5.     <script language="javascript">    
  6.         function CallCppFunSub(x,y)    
  7.         {  
  8.             var num = window.external.g_FunSub(x,y);   
  9.             alert(num);  
  10.             return num  
  11.         }   
  12.         function JsFunSub(x,y)    
  13.         {  
  14.             var num = x - y;  
  15.             alert(num);  
  16.             return num  
  17.         }  
  18.     </script>    
  19. </head>    
  20. <body>  
  21.     <button type="button" onclick="CallCppFunSub(4,7)">调用C++函数</button>    
  22. </body>    
  23. </html>   
具体实现是在C++代码中写的:

[cpp]  view plain  copy
  1. #pragma once  
  2.   
  3. class CWebBrowserExUI :  
  4.     public CWebBrowserUI  
  5. {  
  6. public:  
  7.     CWebBrowserExUI();  
  8.     ~CWebBrowserExUI();  
  9.   
  10.     LPCTSTR GetClass() const;  
  11.     LPVOID GetInterface(LPCTSTR pstrName);  
  12.   
  13.     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);  
  14.     virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);  
  15.   
  16.     virtual HRESULT STDMETHODCALLTYPE GetExternal(IDispatch **ppDispatch)  
  17.     {  
  18.         //重写GetExternal返回一个ClientCall对象  
  19.         *ppDispatch = this;  
  20.         return S_OK;  
  21.     }  
  22. };  

[cpp]  view plain  copy
  1. #include "stdafx.h"  
  2. #include "WebBrowserExUI.h"  
  3. #include <atlcomcli.h>  
  4.   
  5.   
  6. int g_FunSub(int x, int y)  
  7. {  
  8.     return (x - y);  
  9. }  
  10.   
  11. CWebBrowserExUI::CWebBrowserExUI()  
  12. {  
  13. }  
  14.   
  15.   
  16. CWebBrowserExUI::~CWebBrowserExUI()  
  17. {  
  18. }  
  19.   
  20.   
  21. LPCTSTR CWebBrowserExUI::GetClass() const  
  22. {  
  23.     return _T("WebBrowserExUI");  
  24. }  
  25.   
  26. LPVOID CWebBrowserExUI::GetInterface(LPCTSTR pstrName)  
  27. {  
  28.     if (_tcsicmp(pstrName, _T("WebBrowserEx")) == 0)  
  29.         return static_cast<CWebBrowserExUI*>(this);  
  30.   
  31.     return CActiveXUI::GetInterface(pstrName);  
  32. }  
  33.   
  34.   
  35. HRESULT CWebBrowserExUI::GetIDsOfNames(const IID& riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)  
  36. {  
  37.     //DISP ID 从200开始  
  38.     if (_tcscmp(rgszNames[0], _T("g_FunSub")) == 0)  
  39.         *rgDispId = 500;  
  40.   
  41.     return S_OK;  
  42. }  
  43.   
  44. HRESULT CWebBrowserExUI::Invoke(DISPID dispIdMember, const IID& riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)  
  45. {  
  46.     //MyOutputDebugStringW(L"%d\n", dispIdMember);  
  47.     switch (dispIdMember)  
  48.     {  
  49.     case 500:  
  50.     {  
  51.         // 注意参数顺序,反向  
  52.         VARIANTARG *varArg = pDispParams->rgvarg;  
  53.         int x = _ttoi(static_cast<_bstr_t>(varArg[1]));  
  54.         int y = _ttoi(static_cast<_bstr_t>(varArg[0]));  
  55.         int n = g_FunSub(x, y);  
  56.         *pVarResult = CComVariant(n);  
  57.         return S_OK;  
  58.     }  
  59.   
  60.     default:  
  61.         break;  
  62.     }  
  63.   
  64.     return CWebBrowserUI::Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);  
  65. }  



二、C++调用js方法。

[html]  view plain  copy
  1. function JsFunSub(x,y)  
C++中这么调用:

[cpp]  view plain  copy
  1. void CMainFrameWnd::OnClick(TNotifyUI& msg)  
  2. {  
  3.     CDuiString sCtrlName = msg.pSender->GetName();  
  4.   
  5.     if (sCtrlName.CompareNoCase(_T("CallJsBtn")) == 0)  
  6.     {  
  7.         // C++调用js方法,示例  
  8.         // 注意参数顺序,反向  
  9.         VARIANT arg[2] = { CComVariant(7),CComVariant(3)};//JsFunSub(3,7)  
  10.         VARIANT varRet;  
  11.         m_pBrowser->InvokeMethod(m_pBrowser->GetHtmlWindow(),_T("JsFunSub"),&varRet,arg,2);  
  12.         int nResult =  varRet.intVal;//-4  
  13.         return;  
  14.     }  
  15.   
  16.   
  17.     WindowImplBase::OnClick(msg);  
  18. }  

js中这样实现:

[html]  view plain  copy
  1. <html>    
  2. <head>    
  3.     <meta charset="utf-8" />    
  4.     <title></title>    
  5.     <script language="javascript">    
  6.         function CallCppFunSub(x,y)    
  7.         {  
  8.             var num = window.external.g_FunSub(x,y);   
  9.             alert(num);  
  10.             return num  
  11.         }   
  12.         function JsFunSub(x,y)    
  13.         {  
  14.             var num = x - y;  
  15.             alert(num);  
  16.             return num  
  17.         }  
  18.     </script>    
  19. </head>    
  20. <body>  
  21.     <button type="button" onclick="CallCppFunSub(4,7)">调用C++函数</button>    
  22. </body>    
  23. </html>   

执行js务必在网页加载完成时执行,示例代码片段如下:

[cpp]  view plain  copy
  1. void CMyWebBrowserEvenrHandler::NavigateComplete2(CWebBrowserUI* pWeb, IDispatch* pDisp, VARIANT*& url)  
  2. {  
  3.     // 页面加载完毕才能执行js  
  4.     // execute js start   
  5.     IDispatch *pHtmlDocDisp = pWeb->GetHtmlWindow();  
  6.     IHTMLDocument2 *pHtmlDoc2 = NULL;  
  7.     HRESULT hr = pHtmlDocDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc2);  
  8.     pHtmlDocDisp->Release();  
  9.     if (SUCCEEDED(hr) && pHtmlDoc2 != NULL)  
  10.     {  
  11.         CComQIPtr<IHTMLWindow2> pHTMLWnd;  
  12.         pHtmlDoc2->get_parentWindow(&pHTMLWnd);  
  13.         if (SUCCEEDED(hr) && pHTMLWnd != NULL)  
  14.         {  
  15.             //CComBSTR bstrjs = SysAllocString(_T("document.documentElement.style.overflow = 'hidden'"));//去除水平方向滚动条    
  16.             CComBSTR bstrjs = SysAllocString(_T("document.documentElement.style.overflowY = 'hidden'"));//去除竖直方向滚动条    
  17.             CComBSTR bstrlan = SysAllocString(_T("javascript"));  
  18.             VARIANT varRet;  
  19.             pHTMLWnd->execScript(bstrjs, bstrlan, &varRet);  
  20.         }  
  21.     }  
  22.     // execute js end  
  23. }