c++与js脚本交互,C++调用JS函数JS调用C++函数

一、javascript调用c++,方法有两种   方案1:   1.html编写   <html> <head> </head> <body> <h1> TEST </h1> <input type='button'name="xx3" value=调用c++函数 onclick="window.navigate('app:command&arg1=1&arg2=2')"> </body> <script language="javascript"> function TestFunc() { alert("TestFunc"); } </script> </html>   2.C++的CHtmlView类重写OnBeforeNavigate2函数   void CAddGoogleMap_CHtmlView::OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, CByteArray& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel) { // TODO: Add your specialized code here and/or call the base class CString strUrl = lpszURL; if(strUrl.Left(4) == _T("app:")) { // cancel the common url navigate and call your c++ code here *pbCancel = TRUE; MessageBox("调用了C++函数", "来自对话框消息"); // call other c++ function here or parse the argument in the strUrl   }   CHtmlView::OnBeforeNavigate2(lpszURL, nFlags, lpszTargetFrameName, baPostedData, lpszHeaders, pbCancel); }   方案2:   1.编写html   <html>   <head>   </head>   <body>   <script language="javascript"> function CallCpp()   {   alert('start to call cpp here');   window.external.JavaScriptCallCpp('This is a test for call C++ in JavaScript');   }   </script>   <input type='button'name="xx3" value=调用c++函数 onclick="CallCpp()" />   </body>   <html>   2.C++代码   CString javaScriptName = _T("JavaScriptCallCpp");   #define DISPID_CallCppFromJs 1   // 实现IDispatch 接口   // .h class CImpIDispatch : public IDispatch { protected: ULONG m_cRef; public: CImpIDispatch(void); ~CImpIDispatch(void); STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); //IDispatch STDMETHODIMP GetTypeInfoCount(UINT* pctinfo); STDMETHODIMP GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo** ppTInfo); STDMETHODIMP GetIDsOfNames( /* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID *rgDispId); STDMETHODIMP Invoke( /* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS *pDispParams, /* [out] */ VARIANT *pVarResult, /* [out] */ EXCEPINFO *pExcepInfo, /* [out] */ UINT *puArgErr); }; // .cpp STDMETHODIMP CImpIDispatch::QueryInterface( REFIID riid, void **ppv ) { *ppv = NULL; if ( IID_IDispatch == riid ) { *ppv = this; }   if ( NULL != *ppv ) { ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; } return E_NOINTERFACE; } STDMETHODIMP_(ULONG) CImpIDispatch::AddRef(void) { return ++m_cRef; } STDMETHODIMP_(ULONG) CImpIDispatch::Release(void) { return --m_cRef; } //IDispatch STDMETHODIMP CImpIDispatch::GetTypeInfoCount(UINT* /*pctinfo*/) { return E_NOTIMPL; } STDMETHODIMP CImpIDispatch::GetTypeInfo( /* [in] */ UINT /*iTInfo*/, /* [in] */ LCID /*lcid*/, /* [out] */ ITypeInfo** /*ppTInfo*/) { return E_NOTIMPL; } STDMETHODIMP CImpIDispatch::GetIDsOfNames( /* [in] */ REFIID riid, /* [size_is][in] */ OLECHAR** rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID* rgDispId) { HRESULT hr; UINT i; // Assume some degree of success hr = NOERROR; for ( i=0; i < cNames; i++) { CString cszName = rgszNames[i]; if (cszName == javaScriptName) { rgDispId[i] = DISPID_CallCppFromJs; } else { // One or more are unknown so set the return code accordingly hr = ResultFromScode(DISP_E_UNKNOWNNAME); rgDispId[i] = DISPID_UNKNOWN; } } return hr; } STDMETHODIMP CImpIDispatch::Invoke( /* [in] */ DISPID dispIdMember, /* [in] */ REFIID /*riid*/, /* [in] */ LCID /*lcid*/, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS* pDispParams, /* [out] */ VARIANT* pVarResult, /* [out] */ EXCEPINFO* /*pExcepInfo*/, /* [out] */ UINT* puArgErr) { CXXXDlg* pDlg = (CCppCallJsDlg*) AfxGetMainWnd();   if (dispIdMember == DISPID_CallCppFromJs) { if (wFlags & DISPATCH_PROPERTYGET) { if (pVarResult != NULL) { VariantInit(pVarResult); V_VT(pVarResult)=VT_BOOL; V_BOOL(pVarResult)=true; } } if (wFlags & DISPATCH_METHOD) { CString cszArg1= pDispParams->rgvarg[0].bstrVal; pDlg->CallByScript(cszArg1); } } return S_OK; }   // 改写COleControlSit // .h class CCustomControlSite:public COleControlSite { public: CCustomControlSite(COleControlContainer *pCnt):COleControlSite(pCnt){}   BEGIN_INTERFACE_PART(DocHostShowUI, IDocHostShowUI) INIT_INTERFACE_PART(CDocHostSite, DocHostShowUI) STDMETHOD(ShowHelp)( /* [in ] */ HWND hwnd, /* [in ] */ LPOLESTR pszHelpFile, /* [in ] */ UINT uCommand, /* [in ] */ DWORD dwData, /* [in ] */ POINT ptMouse, /* [out] */ IDispatch __RPC_FAR *pDispatchObjectHit); STDMETHOD(ShowMessage)( /* [in ] */ HWND hwnd, /* [in ] */ LPOLESTR lpstrText, /* [in ] */ LPOLESTR lpstrCaption, /* [in ] */ DWORD dwType, /* [in ] */ LPOLESTR lpstrHelpFile, /* [in ] */ DWORD dwHelpContext, /* [out] */ LRESULT __RPC_FAR *plResult); END_INTERFACE_PART(DocHostShowUI) protected: DECLARE_INTERFACE_MAP(); BEGIN_INTERFACE_PART(DocHostUIHandler, IDocHostUIHandler) STDMETHOD(ShowContextMenu)(/* [in] */ DWORD dwID, /* [in] */ POINT __RPC_FAR *ppt, /* [in] */ IUnknown __RPC_FAR *pcmdtReserved, /* [in] */ IDispatch __RPC_FAR *pdispReserved); STDMETHOD(GetHostInfo)( /* [out][in] */ DOCHOSTUIINFO __RPC_FAR *pInfo); STDMETHOD(ShowUI)( /* [in] */ DWORD dwID, /* [in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject, /* [in] */ IOleCommandTarget __RPC_FAR *pCommandTarget, /* [in] */ IOleInPlaceFrame __RPC_FAR *pFrame, /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pDoc); STDMETHOD(HideUI)(void); STDMETHOD(UpdateUI)(void); STDMETHOD(EnableModeless)(/* [in] */ BOOL fEnable); STDMETHOD(OnDocWindowActivate)(/* [in] */ BOOL fEnable); STDMETHOD(OnFrameWindowActivate)(/* [in] */ BOOL fEnable); STDMETHOD(ResizeBorder)( /* [in] */ LPCRECT prcBorder, /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pUIWindow, /* [in] */ BOOL fRameWindow); STDMETHOD(TranslateAccelerator)( /* [in] */ LPMSG lpMsg, /* [in] */ const GUID __RPC_FAR *pguidCmdGroup, /* [in] */ DWORD nCmdID); STDMETHOD(GetOptionKeyPath)( /* [out] */ LPOLESTR __RPC_FAR *pchKey, /* [in] */ DWORD dw); STDMETHOD(GetDropTarget)( /* [in] */ IDropTarget __RPC_FAR *pDropTarget, /* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget); STDMETHOD(GetExternal)( /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch); STDMETHOD(TranslateUrl)( /* [in] */ DWORD dwTranslate, /* [in] */ OLECHAR __RPC_FAR *pchURLIn, /* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut); STDMETHOD(FilterDataObject)( /* [in] */ IDataObject __RPC_FAR *pDO, /* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet); END_INTERFACE_PART(DocHostUIHandler) }; class CCustomOccManager :public COccManager { public: CCustomOccManager(){} COleControlSite* CreateSite(COleControlContainer* pCtrlCont) { CCustomControlSite *pSite = new CCustomControlSite(pCtrlCont); return pSite; } }; // .cpp BEGIN_INTERFACE_MAP(CCustomControlSite, COleControlSite) INTERFACE_PART(CCustomControlSite, IID_IDocHostShowUI, DocHostShowUI) INTERFACE_PART(CCustomControlSite, IID_IDocHostUIHandler, DocHostUIHandler) END_INTERFACE_MAP() ULONG CCustomControlSite::XDocHostShowUI::AddRef() { METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI); return pThis->ExternalAddRef(); } ULONG CCustomControlSite::XDocHostShowUI::Release() { METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI); return pThis->ExternalRelease(); } HRESULT CCustomControlSite::XDocHostShowUI::QueryInterface(REFIID riid, void ** ppvObj) { METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI); return pThis->ExternalQueryInterface( &riid, ppvObj ); } HRESULT CCustomControlSite::XDocHostShowUI::ShowHelp(HWND hwnd, LPOLESTR pszHelpFile, UINT nCommand, DWORD dwData, POINT ptMouse, IDispatch * pDispatchObjectHit) { METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI); return S_OK; } HRESULT CCustomControlSite::XDocHostShowUI::ShowMessage(HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT * plResult) { METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI);   MessageBox(hwnd, (CString)lpstrText, _T("Cpp & JavaScript"), /*dwType*/MB_ICONWARNING); return S_OK; } ULONG FAR EXPORT CCustomControlSite::XDocHostUIHandler::AddRef() { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return pThis->ExternalAddRef(); } ULONG FAR EXPORT CCustomControlSite::XDocHostUIHandler::Release() { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return pThis->ExternalRelease(); } HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::QueryInterface(REFIID riid, void **ppvObj) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj); return hr; } // * CImpIDocHostUIHandler::GetHostInfo // * // * Purpose: Called at initialization // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::GetHostInfo( DOCHOSTUIINFO* pInfo ) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER; pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; return S_OK; } // * CImpIDocHostUIHandler::ShowUI // * // * Purpose: Called when MSHTML.DLL shows its UI // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ShowUI( DWORD dwID, IOleInPlaceActiveObject * /*pActiveObject*/, IOleCommandTarget * pCommandTarget, IOleInPlaceFrame * /*pFrame*/, IOleInPlaceUIWindow * /*pDoc*/) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) // We've already got our own UI in place so just return S_OK return S_OK; } // * CImpIDocHostUIHandler::HideUI // * // * Purpose: Called when MSHTML.DLL hides its UI // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::HideUI(void) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return S_OK; } // * CImpIDocHostUIHandler::UpdateUI // * // * Purpose: Called when MSHTML.DLL updates its UI // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::UpdateUI(void) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) // MFC is pretty good about updating it's UI in it's Idle loop so I don't do anything here return S_OK; } // * CImpIDocHostUIHandler::EnableModeless // * // * Purpose: Called from MSHTML.DLL's IOleInPlaceActiveObject::EnableModeless // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::EnableModeless(BOOL /*fEnable*/) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL; } // * CImpIDocHostUIHandler::OnDocWindowActivate // * // * Purpose: Called from MSHTML.DLL's IOleInPlaceActiveObject::OnDocWindowActivate // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::OnDocWindowActivate(BOOL /*fActivate*/) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL; } // * CImpIDocHostUIHandler::OnFrameWindowActivate // * // * Purpose: Called from MSHTML.DLL's IOleInPlaceActiveObject::OnFrameWindowActivate // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::OnFrameWindowActivate(BOOL /*fActivate*/) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL; } // * CImpIDocHostUIHandler::ResizeBorder // * // * Purpose: Called from MSHTML.DLL's IOleInPlaceActiveObject::ResizeBorder // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ResizeBorder( LPCRECT /*prcBorder*/, IOleInPlaceUIWindow* /*pUIWindow*/, BOOL /*fRameWindow*/) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL; } // * CImpIDocHostUIHandler::ShowContextMenu // * // * Purpose: Called when MSHTML.DLL would normally display its context menu // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ShowContextMenu( DWORD /*dwID*/, POINT* pptPosition, IUnknown* /*pCommandTarget*/, IDispatch* /*pDispatchObjectHit*/) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL;   //CMenu menu; //menu.LoadMenu(IDR_CUSTOM_POPUP); //CMenu* pSubMenu = menu.GetSubMenu(0); ////Because we passed in theApp.m_pMainWnd all of our ////WM_COMMAND handlers for the menu items must be handled ////in CCustomBrowserApp. If you want this to be your dialog ////you will have to grab a pointer to your dialog class and ////pass the hWnd of it into the last parameter in this call //pSubMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, pptPosition->x, pptPosition->y, theApp.m_pMainWnd); return S_OK; // We've shown our own context menu. MSHTML.DLL will no longer try to show its own. } // * CImpIDocHostUIHandler::TranslateAccelerator // * // * Purpose: Called from MSHTML.DLL's TranslateAccelerator routines // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::TranslateAccelerator(LPMSG lpMsg, /* [in] */ const GUID __RPC_FAR *pguidCmdGroup, /* [in] */ DWORD nCmdID) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)   //disable F5 if(lpMsg->message == WM_KEYDOWN && GetAsyncKeyState(VK_F5) < 0) return S_OK; if(GetKeyState(VK_CONTROL) & 0x8000) { //disable ctrl + O if(lpMsg->message == WM_KEYDOWN && GetAsyncKeyState(0x4F) < 0) return S_OK; //disable ctrl + p if(lpMsg->message == WM_KEYDOWN && GetAsyncKeyState(0x50) < 0) return S_OK; //disable ctrl + N if(lpMsg->message == WM_KEYDOWN && GetAsyncKeyState(0x4E) < 0) return S_OK; } //disable back space if(lpMsg->wParam == VK_BACK) return S_OK; return S_FALSE; } // * CImpIDocHostUIHandler::GetOptionKeyPath // * // * Purpose: Called by MSHTML.DLL to find where the host wishes to store // * its options in the registry // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::GetOptionKeyPath(BSTR* pbstrKey, DWORD) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL; } STDMETHODIMP CCustomControlSite::XDocHostUIHandler::GetDropTarget( /* [in] */ IDropTarget __RPC_FAR *pDropTarget, /* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL; } STDMETHODIMP CCustomControlSite::XDocHostUIHandler::GetExternal( /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) { // return the IDispatch we have for extending the object Model IDispatch* pDisp = (IDispatch*)theApp.m_pDispOM; pDisp->AddRef(); *ppDispatch = pDisp; return S_OK; }   STDMETHODIMP CCustomControlSite::XDocHostUIHandler::TranslateUrl( /* [in] */ DWORD dwTranslate, /* [in] */ OLECHAR __RPC_FAR *pchURLIn, /* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL; }   STDMETHODIMP CCustomControlSite::XDocHostUIHandler::FilterDataObject( /* [in] */ IDataObject __RPC_FAR *pDO, /* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet) { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler) return E_NOTIMPL; }   // 修改App // .h class CImpIDispatch; class CXXXApp : public CWinApp {   CImpIDispatch *m_pDispOM;   } // .cpp BOOL CXXXApp::InitInstance() {   CWinApp::InitInstance(); CCustomOccManager *pMgr = new CCustomOccManager; // Create an IDispatch class for extending the Dynamic HTML Object Model m_pDispOM = new CImpIDispatch; // Set our control containment up but using our control container // management class instead of MFC's default AfxEnableControlContainer(pMgr);   }   二、C++调用javascript函数   1.编写html,如javascript调用c++的方案1的html   2.c++代码   void CAddGoogleMap_CHtmlView::OnTestSwap() { // call js function CComPtr<IDispatch> spScript; CComPtr<IHTMLDocument2> spDoc; GetHtmlDocument()->QueryInterface(IID_IHTMLDocument2,(void**)&spDoc);//取得网页文档接口指针 spDoc->get_Script(&spScript);//取得脚本com接口   CComBSTR bstrMember("TestFunc");//javaScript函数名称 DISPID dispid = NULL; HRESULT hr = spScript->GetIDsOfNames(IID_NULL,&bstrMember,1, LOCALE_SYSTEM_DEFAULT,&dispid);//取得函数名对应 DISPID DISPPARAMS dispparams;//根据实际函数情况填写函数参数,这里示例TestFunc函数没有参数据 memset(&dispparams, 0, sizeof dispparams); dispparams.cArgs = 0;//参数个数 dispparams.rgvarg = new VARIANT[dispparams.cArgs]; dispparams.cNamedArgs = 0;   EXCEPINFO excepInfo; memset(&excepInfo, 0, sizeof excepInfo); CComVariant vaResult; UINT nArgErr = (UINT)-1; // initialize to invalid arg //执行JavaScript函数 hr = spScript->Invoke(dispid,IID_NULL,0, DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr);   }  
上一篇:显示硬件发展与视频开发系列(5)----智能时代04--编程语言


下一篇:cad.net c#仿lisp的mapcar函数