JavaScript调用C++

方案一:

 

// html & JavaScript

...

<button value="Click me" οnclick="window.navigate('app:command&arg1=1&arg2=2')" />

...

 // C++: 响应 的消息函数OnBeforeNavigat2 

virtual void OnBeforeNavigate2( LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, 

CByteArray& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel );

// C++ code goes here
ContractedBlock.gif ExpandedBlockStart.gif Code
CXXXDlg::OnBeforeNavigate2( LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName,
   CByteArray
& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel )
{
  CString strUrl 
= lpszURL;
  
if(strUrl.Left(4== _T("app:"))
  {
    
// cancel the common url navigate and call your c++ code here
    *pbCancel = TURE;
    
// call other c++ function here or parse the argument in the strUrl
    
  }
  
// go common url navigate here
  
}

方案二:

// html & javaScript

...

function CallCpp()

{

alert('start to call cpp here');

window.external.JavaScriptCallCpp('This is a test for call C++ in JavaScript');

}

<button οnclick="CallCpp()" >JavaScript访问C++代码</button>

...

// C++ code goes here

CString javaScriptName = _T("JavaScriptCallCpp");

#define DISPID_CallCppFromJs 1

// 实现IDispatch 接口

ContractedBlock.gif ExpandedBlockStart.gif Code
// .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
ContractedBlock.gif ExpandedBlockStart.gif Code
// .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
ContractedBlock.gif ExpandedBlockStart.gif Code
// .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);
   
}

 

转载于:https://www.cnblogs.com/dlbrant/archive/2009/02/17/1392430.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值