在JavaScript 调用C++

来源:互联网 发布:sql join where 区别 编辑:程序博客网 时间:2024/05/20 21:19


方案一:

// 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, 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 onclick="CallCpp()" > JavaScript访问C++代码</button>

...

// C++ code goes here

CString javaScriptName = _T("JavaScriptCallCpp");

#define DISPID_CallCppFromJs 1

// 实现IDispatch 接口

// .hclass 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);};// .cppSTDMETHODIMP 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;}//IDispatchSTDMETHODIMP 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

// .hclass 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;    }};// .cppBEGIN_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

// .hclass CImpIDispatch;class CXXXApp : public CWinApp{    CImpIDispatch    *m_pDispOM;  }// .cppBOOL 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);   }


转自:

http://blog.csdn.net/sky04/article/details/5538535






0 0
原创粉丝点击