您的位置:首页 > 编程语言 > C语言/C++

mfc中web插件与c++之间相互调用方案

2016-10-31 21:28 381 查看
一、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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: