JavaScript 调用 C++

来源:互联网 发布:sd数据恢复免费软件 编辑:程序博客网 时间:2024/05/20 16:34
JavaScript调用C++

方案一:

 

// html & JavaScript

...

<button value="Click me"onclick="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


CXXXDlg::OnBeforeNavigate2( LPCTSTR lpszURL, DWORD nFlags, LPCTSTRlpszTargetFrameName,
   CByteArray&baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel)
{
  CString strUrl = lpszURL;
  if(strUrl.Left(4) ==_T("app:"))
  {
    // cancelthe common url navigate and call your c++ codehere
    *pbCancel =TURE;
    // callother c++ function here or parse the argument in thestrUrl
    
  }
  // 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++ inJavaScript');

}

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

...

// C++ code goes here

CString javaScriptName = _T("JavaScriptCallCpp");

#define DISPID_CallCppFromJs 1

// 实现IDispatch 接口
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( UINT iTInfo,
           LCID lcid,
           ITypeInfo** ppTInfo);
       STDMETHODIMP GetIDsOfNames(
           REFIID riid,
           LPOLESTR *rgszNames,
           UINT cNames,
           LCID lcid,
           DISPID *rgDispId);
       STDMETHODIMP Invoke(
           DISPID dispIdMember,
           REFIID riid,
           LCID lcid,
           WORD wFlags,
           DISPPARAMS  *pDispParams,
           VARIANT  *pVarResult,
           EXCEPINFO *pExcepInfo,
           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;
   }

    returnE_NOINTERFACE;
}


STDMETHODIMP_(ULONG) CImpIDispatch::AddRef(void)
{
    return++m_cRef;
}

STDMETHODIMP_(ULONG) CImpIDispatch::Release(void)
{
    return--m_cRef;
}


//IDispatch
STDMETHODIMP CImpIDispatch::GetTypeInfoCount(UINT*)
{
    returnE_NOTIMPL;
}

STDMETHODIMP CImpIDispatch::GetTypeInfo(
           UINT ,
           LCID ,
           ITypeInfo** )
{
    returnE_NOTIMPL;
}

STDMETHODIMP CImpIDispatch::GetIDsOfNames(
           REFIID riid,
           OLECHAR** rgszNames,
           UINT cNames,
           LCID lcid,
           DISPID* rgDispId)
{
    HRESULThr;
   UINT   i;

    // Assumesome 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 codeaccordingly
           hr = ResultFromScode(DISP_E_UNKNOWNNAME);
           rgDispId[i] = DISPID_UNKNOWN;
       }
   }
    returnhr;
}

STDMETHODIMP CImpIDispatch::Invoke(
           DISPID dispIdMember,
           REFIID ,
           LCID ,
           WORD wFlags,
           DISPPARAMS* pDispParams,
           VARIANT* pVarResult,
           EXCEPINFO* ,
           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);
       }
   }

    returnS_OK;
}

// 改写COleControlSit

Code
// .h
class CCustomControlSite:public COleControlSite
{
public:
   CCustomControlSite(COleControlContainer*pCnt):COleControlSite(pCnt){}

    
BEGIN_INTERFACE_PART(DocHostShowUI,IDocHostShowUI)
       INIT_INTERFACE_PART(CDocHostSite, DocHostShowUI)
       STDMETHOD(ShowHelp)(
               HWNDhwnd,
               LPOLESTRpszHelpFile,
               UINTuCommand,
               DWORDdwData,
               POINTptMouse,
               IDispatch__RPC_FAR *pDispatchObjectHit);
       STDMETHOD(ShowMessage)(
               HWNDhwnd,
               LPOLESTRlpstrText,
               LPOLESTRlpstrCaption,
               DWORDdwType,
               LPOLESTRlpstrHelpFile,
               DWORDdwHelpContext,
               LRESULT__RPC_FAR *plResult);
   END_INTERFACE_PART(DocHostShowUI)

protected:

   DECLARE_INTERFACE_MAP();
BEGIN_INTERFACE_PART(DocHostUIHandler,IDocHostUIHandler)
   STDMETHOD(ShowContextMenu)( DWORD dwID,
           POINT __RPC_FAR *ppt,
           IUnknown __RPC_FAR *pcmdtReserved,
           IDispatch __RPC_FAR *pdispReserved);
   STDMETHOD(GetHostInfo)( 
           DOCHOSTUIINFO __RPC_FAR *pInfo);
   STDMETHOD(ShowUI)( 
           DWORD dwID,
           IOleInPlaceActiveObject __RPC_FAR *pActiveObject,
           IOleCommandTarget __RPC_FAR *pCommandTarget,
           IOleInPlaceFrame __RPC_FAR *pFrame,
           IOleInPlaceUIWindow __RPC_FAR *pDoc);
   STDMETHOD(HideUI)(void);
   STDMETHOD(UpdateUI)(void);
   STDMETHOD(EnableModeless)( BOOL fEnable);
   STDMETHOD(OnDocWindowActivate)( BOOL fEnable);
   STDMETHOD(OnFrameWindowActivate)( BOOL fEnable);
   STDMETHOD(ResizeBorder)( 
           LPCRECT prcBorder,
           IOleInPlaceUIWindow __RPC_FAR *pUIWindow,
           BOOL fRameWindow);
   STDMETHOD(TranslateAccelerator)( 
           LPMSG lpMsg,
           const GUID __RPC_FAR *pguidCmdGroup,
           DWORD nCmdID);
   STDMETHOD(GetOptionKeyPath)( 
           LPOLESTR __RPC_FAR *pchKey,
           DWORD dw);
   STDMETHOD(GetDropTarget)(
           IDropTarget __RPC_FAR *pDropTarget,
           IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget);
   STDMETHOD(GetExternal)( 
           IDispatch __RPC_FAR *__RPC_FAR *ppDispatch);
   STDMETHOD(TranslateUrl)( 
           DWORD dwTranslate,
           OLECHAR __RPC_FAR *pchURLIn,
           OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut);
   STDMETHOD(FilterDataObject)( 
           IDataObject __RPC_FAR *pDO,
           IDataObject __RPC_FAR *__RPC_FAR *ppDORet);
END_INTERFACE_PART(DocHostUIHandler)
};


class CCustomOccManager :public COccManager
{
public:
   CCustomOccManager(){}
   COleControlSite* CreateSite(COleControlContainer*pCtrlCont)
   {
       CCustomControlSite *pSite = newCCustomControlSite(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);

    returnpThis->ExternalAddRef();
}

ULONGCCustomControlSite::XDocHostShowUI::Release()
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostShowUI);

    returnpThis->ExternalRelease();
}

HRESULT CCustomControlSite::XDocHostShowUI::QueryInterface(REFIIDriid, void ** ppvObj)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostShowUI);

    returnpThis->ExternalQueryInterface(&riid, ppvObj );
}


HRESULT CCustomControlSite::XDocHostShowUI::ShowHelp(HWNDhwnd,
                                              LPOLESTR pszHelpFile,
                                              UINT nCommand,
                                              DWORD dwData,
                                              POINT ptMouse,
                                              IDispatch * pDispatchObjectHit)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostShowUI);

    returnS_OK;
}

HRESULT CCustomControlSite::XDocHostShowUI::ShowMessage(HWNDhwnd,
                                                 LPOLESTR lpstrText,
                                                 LPOLESTR lpstrCaption,
                                                 DWORD dwType,
                                                 LPOLESTR lpstrHelpFile,
                                                 DWORD dwHelpContext,
                                                 LRESULT * plResult)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostShowUI);
    
   MessageBox(hwnd, (CString)lpstrText, _T("Cpp &JavaScript"), MB_ICONWARNING);

    returnS_OK;
}


ULONG FAR EXPORT CCustomControlSite::XDocHostUIHandler::AddRef()
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnpThis->ExternalAddRef();
}


ULONG FAR EXPORT CCustomControlSite::XDocHostUIHandler::Release()
                           
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnpThis->ExternalRelease();
}

HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::QueryInterface(REFIID riid,void **ppvObj)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    HRESULT hr =(HRESULT)pThis->ExternalQueryInterface(&riid,ppvObj);
    returnhr;
}

// * 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;

    returnS_OK;
}

// * CImpIDocHostUIHandler::ShowUI
// *
// * Purpose: Called when MSHTML.DLL shows its UI
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ShowUI(
               DWORD dwID, 
               IOleInPlaceActiveObject * ,
               IOleCommandTarget * pCommandTarget,
               IOleInPlaceFrame * ,
               IOleInPlaceUIWindow * )
{

   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    // We'vealready got our own UI in place so just returnS_OK
    returnS_OK;
}

// * CImpIDocHostUIHandler::HideUI
// *
// * Purpose: Called when MSHTML.DLL hides its UI
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::HideUI(void)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnS_OK;
}

// * CImpIDocHostUIHandler::UpdateUI
// *
// * Purpose: Called when MSHTML.DLL updates itsUI
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::UpdateUI(void)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    // MFC ispretty good about updating it's UI in it's Idle loop so I don't doanything here
    returnS_OK;
}

// * CImpIDocHostUIHandler::EnableModeless
// *
// * Purpose: Called from MSHTML.DLL'sIOleInPlaceActiveObject::EnableModeless
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::EnableModeless(BOOL)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
}

// * CImpIDocHostUIHandler::OnDocWindowActivate
// *
// * Purpose: Called from MSHTML.DLL'sIOleInPlaceActiveObject::OnDocWindowActivate
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::OnDocWindowActivate(BOOL)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
}

// * CImpIDocHostUIHandler::OnFrameWindowActivate
// *
// * Purpose: Called from MSHTML.DLL'sIOleInPlaceActiveObject::OnFrameWindowActivate
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::OnFrameWindowActivate(BOOL)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
}

// * CImpIDocHostUIHandler::ResizeBorder
// *
// * Purpose: Called from MSHTML.DLL'sIOleInPlaceActiveObject::ResizeBorder
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ResizeBorder(
               LPCRECT , 
               IOleInPlaceUIWindow* ,
               BOOL )
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
}

// * CImpIDocHostUIHandler::ShowContextMenu
// *
// * Purpose: Called when MSHTML.DLL would normally display itscontext menu
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ShowContextMenu(
               DWORD , 
               POINT* pptPosition,
               IUnknown* ,
               IDispatch* )
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
    
    //CMenumenu;
   //menu.LoadMenu(IDR_CUSTOM_POPUP);
    //CMenu*pSubMenu = menu.GetSubMenu(0);
    ////Becausewe passed in theApp.m_pMainWnd all of our
   ////WM_COMMAND handlers for the menu items must behandled
    ////inCCustomBrowserApp. If you want this to be yourdialog
    ////you willhave to grab a pointer to your dialog classand 
    ////pass thehWnd 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 tryto show its own.
}

// * CImpIDocHostUIHandler::TranslateAccelerator
// *
// * Purpose: Called from MSHTML.DLL's TranslateAcceleratorroutines
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::TranslateAccelerator(LPMSGlpMsg,
           const GUID __RPC_FAR *pguidCmdGroup,
           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;

    returnS_FALSE;
}

// * CImpIDocHostUIHandler::GetOptionKeyPath
// *
// * Purpose: Called by MSHTML.DLL to find where the host wishes tostore 
// *    itsoptions in the registry
// *
HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::GetOptionKeyPath(BSTR*pbstrKey, DWORD)
{

   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
}

STDMETHODIMPCCustomControlSite::XDocHostUIHandler::GetDropTarget( 
           IDropTarget __RPC_FAR *pDropTarget,
           IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
}


STDMETHODIMPCCustomControlSite::XDocHostUIHandler::GetExternal( 
           IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
{
    // returnthe IDispatch we have for extending the objectModel
    IDispatch*pDisp = (IDispatch*)theApp.m_pDispOM;
   pDisp->AddRef();
    *ppDispatch= pDisp;
    returnS_OK;
}
        
STDMETHODIMPCCustomControlSite::XDocHostUIHandler::TranslateUrl( 
           DWORD dwTranslate,
           OLECHAR __RPC_FAR *pchURLIn,
           OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
}
        
STDMETHODIMPCCustomControlSite::XDocHostUIHandler::FilterDataObject( 
           IDataObject __RPC_FAR *pDO,
           IDataObject __RPC_FAR *__RPC_FAR *ppDORet)
{
   METHOD_PROLOGUE(CCustomControlSite,DocHostUIHandler)
    returnE_NOTIMPL;
}


// 修改App

Code
// .h
class CImpIDispatch;
class CXXXApp : public CWinApp
{
  
 CImpIDispatch   *m_pDispOM;
  
}

// .cpp
BOOL CXXXApp::InitInstance()
{
   
   CWinApp::InitInstance();

   CCustomOccManager *pMgr = new CCustomOccManager;
    // Create anIDispatch class for extending the Dynamic HTML ObjectModel 
    m_pDispOM =new CImpIDispatch;
    // Set ourcontrol containment up but using our controlcontainer 
    //management class instead of MFC's default
   AfxEnableControlContainer(pMgr);
   
}
link:http://www.cnblogs.com/dlbrant/archive/2009/02/17/1392430.html