MFC对话框里利用CHtmlView加载界面(三)————JaveScript 调用 MFC

前言

 MFC对话框里利用CHtmlView加载界面(二)———— MFC 调用 JaveScript中,我们实现MFC对JaveScript方法的调用。

现在我们想既然MFC能调用JaveScript,那么又该如何实现JaveScript调用MFC呢?

只有MFC 能和 JaveScript 实现互相调用,那我们完全就可以将HTML作为我们的界面,将MFC作为我们底层逻辑的处理,实现漂亮的界面了。


相比MFC 调用 JavaScript 只需要获取COM接口,封装几个函数就能实现调用,JavaScript调用MFC就想到复杂很多。

里面涉及了ActiveX编程知识,需要根据浏览器定义的一些扩展接口,对其进行定制和扩展。

CDocHostSite类实现

首先我们要实现CHtmlView的控制站点类,在此定义为CDocHostSite类。

CDocHostSite类继承自COleControlSite类,实现了IDocHostShowUI、IDocHostUIHandler、IDocHostUIHandler2、IInternetSecurityManager接口。

对于它的具体实现,由于其涉及了很多ActiveX编程知识,理解起来比较困难。但作为ActiveX小白,我们其实并不需要太多关心具体实现,只需要直接复制拷贝,能用就行。

需要注意的一点是:在实现中,我们只需要将CDocHostSite代码中的CBaseHtmlView类改成你自己实现的类就行了。

CDocHostSite类的申明如下:

#include <afxocc.h>

class CBaseHtmlView;

class CDocHostSite : public COleControlSite
{
public:
    CDocHostSite(COleControlContainer * pOCC, CBaseHtmlView* pView);
    virtual ~CDocHostSite();

private:
    CBaseHtmlView* m_pView;

// IDocHostShowUI
protected:
    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)

// IDocHostUIHandler
protected:
    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)

#if (_WIN32_IE >= 0x0501) // IE 5.5 and higher
// IDocHostUIHandler2
protected:
    BEGIN_INTERFACE_PART(DocHostUIHandler2, IDocHostUIHandler2)
    STDMETHOD(GetOverrideKeyPath)(
        /* [out] */ LPOLESTR __RPC_FAR *pchKey,
        /* [in] */ DWORD dw);
    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(DocHostUIHandler2)
#endif

// Implement IInternetSecurityManager
    BEGIN_INTERFACE_PART(InternetSecurityManager, IInternetSecurityManager)
    STDMETHOD(SetSecuritySite)(IInternetSecurityMgrSite*);
    STDMETHOD(GetSecuritySite)(IInternetSecurityMgrSite**);
    STDMETHOD(MapUrlToZone)(LPCWSTR,DWORD*,DWORD);
    STDMETHOD(GetSecurityId)(LPCWSTR, BYTE*, DWORD*, DWORD_PTR);
    STDMETHOD(ProcessUrlAction)(
        /* [in] */ LPCWSTR pwszUrl,
        /* [in] */ DWORD dwAction,
        /* [size_is][out] */ BYTE __RPC_FAR *pPolicy,
        /* [in] */ DWORD cbPolicy,
        /* [in] */ BYTE __RPC_FAR *pContext,
        /* [in] */ DWORD cbContext,
        /* [in] */ DWORD dwFlags,
        /* [in] */ DWORD dwReserved = 0);
    STDMETHOD(QueryCustomPolicy)(LPCWSTR,REFGUID,BYTE**,DWORD*,BYTE*,DWORD,DWORD);
    STDMETHOD(SetZoneMapping)(DWORD,LPCWSTR,DWORD);
    STDMETHOD(GetZoneMappings)(DWORD,IEnumString**,DWORD);
    END_INTERFACE_PART(InternetSecurityManager)


///
 Implement IServiceProvider
    BEGIN_INTERFACE_PART(ServiceProvider, IServiceProvider)
    STDMETHOD(QueryService)(REFGUID,REFIID,void**);
    END_INTERFACE_PART(ServiceProvider)

    DECLARE_INTERFACE_MAP()
};
实现部分为:

#include "stdafx.h"

#if _MFC_VER >= 0x0700
#include <afxocc.h>
#else
#ifdef _AFXDLL
#undef AFX_DATA
#define AFX_DATA AFX_DATA_IMPORT
#endif
#include <..\src\occimpl.h>
#ifdef _AFXDLL
#undef AFX_DATA
#define AFX_DATA AFX_DATA_EXPORT
#endif
#endif

#include <mshtmhst.h>

#include "DocHostSite.h"
#include "BaseHtmlView.h"

BEGIN_INTERFACE_MAP(CDocHostSite, COleControlSite)
INTERFACE_PART(CDocHostSite, IID_IDocHostShowUI, DocHostShowUI)
INTERFACE_PART(CDocHostSite, IID_IDocHostUIHandler, DocHostUIHandler)
#if (_WIN32_IE >= 0x0501) // IE 5.5 and higher
INTERFACE_PART(CDocHostSite, IID_IDocHostUIHandler2, DocHostUIHandler2)
#endif
INTERFACE_PART(CDocHostSite, IID_IInternetSecurityManager, InternetSecurityManager)
INTERFACE_PART(CDocHostSite, IID_IServiceProvider, ServiceProvider)
END_INTERFACE_MAP()

CDocHostSite::CDocHostSite(COleControlContainer * pOcc, CBaseHtmlView* pView)
        : COleControlSite( pOcc )
{
    m_pView = pView;
}

CDocHostSite::~CDocHostSite()
{
}

ULONG CDocHostSite::XDocHostShowUI::AddRef()
{
    METHOD_PROLOGUE(CDocHostSite, DocHostShowUI);

    return pThis->ExternalAddRef();
}

ULONG CDocHostSite::XDocHostShowUI::Release()
{
    METHOD_PROLOGUE(CDocHostSite, DocHostShowUI);

    return pThis->ExternalRelease();
}

HRESULT CDocHostSite::XDocHostShowUI::QueryInterface(REFIID riid, void ** ppvObj)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostShowUI);

    return pThis->ExternalQueryInterface( &riid, ppvObj );
}

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

    return E_NOTIMPL;
}

HRESULT CDocHostSite::XDocHostShowUI::ShowMessage(HWND hwnd,
        LPOLESTR lpstrText,
        LPOLESTR lpstrCaption,
        DWORD dwType,
        LPOLESTR lpstrHelpFile,
        DWORD dwHelpContext,
        LRESULT * plResult)
{
	METHOD_PROLOGUE(CDocHostSite, DocHostShowUI);

	return pThis->m_pView->OnShowMessage(hwnd,lpstrText,lpstrCaption,dwType,lpstrHelpFile,dwHelpContext,plResult);
}

ULONG CDocHostSite::XDocHostUIHandler::AddRef()
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->ExternalAddRef();
}

ULONG CDocHostSite::XDocHostUIHandler::Release()
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->ExternalRelease();
}

HRESULT CDocHostSite::XDocHostUIHandler::QueryInterface(REFIID riid, void ** ppvObj)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->ExternalQueryInterface( &riid, ppvObj );
}

HRESULT CDocHostSite::XDocHostUIHandler::GetHostInfo(DOCHOSTUIINFO * pInfo)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnGetHostInfo( pInfo );
}

HRESULT CDocHostSite::XDocHostUIHandler::ShowUI(DWORD dwID,
        IOleInPlaceActiveObject * pActiveObject,
        IOleCommandTarget * pCommandTarget,
        IOleInPlaceFrame * pFrame,
        IOleInPlaceUIWindow * pDoc)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnShowUI( dwID, pActiveObject, pCommandTarget,
                                     pFrame, pDoc );
}

HRESULT CDocHostSite::XDocHostUIHandler::HideUI()
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnHideUI();
}

HRESULT CDocHostSite::XDocHostUIHandler::UpdateUI()
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnUpdateUI();
}

HRESULT CDocHostSite::XDocHostUIHandler::EnableModeless(BOOL fEnable)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnEnableModeless( fEnable );
}

HRESULT CDocHostSite::XDocHostUIHandler::OnDocWindowActivate(BOOL fEnable)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnDocWindowActivate( fEnable );
}

HRESULT CDocHostSite::XDocHostUIHandler::OnFrameWindowActivate(BOOL fEnable)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnFrameWindowActivate( fEnable );
}

HRESULT CDocHostSite::XDocHostUIHandler::ResizeBorder(LPCRECT prcBorder,
        IOleInPlaceUIWindow * pUIWindow,
        BOOL fFrameWindow)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnResizeBorder( prcBorder, pUIWindow, fFrameWindow );
}

HRESULT CDocHostSite::XDocHostUIHandler::ShowContextMenu(DWORD dwID,
        POINT * ppt,
        IUnknown * pcmdtReserved,
        IDispatch * pdispReserved)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnShowContextMenu( dwID, ppt, pcmdtReserved,
            pdispReserved );
}

HRESULT CDocHostSite::XDocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,
        const GUID * pguidCmdGroup,
        DWORD nCmdID)
{
	METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
	return E_NOTIMPL;
	return pThis->m_pView->OnTranslateAccelerator( lpMsg,
		pguidCmdGroup, nCmdID );
}

HRESULT CDocHostSite::XDocHostUIHandler::GetOptionKeyPath(LPOLESTR * pchKey,
        DWORD dw)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnGetOptionKeyPath( pchKey, dw );
}

HRESULT CDocHostSite::XDocHostUIHandler::GetDropTarget(IDropTarget * pDropTarget,
        IDropTarget ** ppDropTarget)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnGetDropTarget( pDropTarget, ppDropTarget );
}

HRESULT CDocHostSite::XDocHostUIHandler::GetExternal(IDispatch ** ppDispatch)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnGetExternal( ppDispatch );
}

HRESULT CDocHostSite::XDocHostUIHandler::TranslateUrl(DWORD dwTranslate,
        OLECHAR * pchURLIn,
        OLECHAR ** ppchURLOut)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnTranslateUrl( dwTranslate, pchURLIn, ppchURLOut );
}

HRESULT CDocHostSite::XDocHostUIHandler::FilterDataObject(IDataObject * pDO,
        IDataObject ** ppDORet)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
    return pThis->m_pView->OnFilterDataObject( pDO, ppDORet );
}

#if (_WIN32_IE >= 0x0501) // IE 5.5 and higher

ULONG CDocHostSite::XDocHostUIHandler2::AddRef()
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler2);

    return pThis->ExternalAddRef();
}

ULONG CDocHostSite::XDocHostUIHandler2::Release()
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler2);

    return pThis->ExternalRelease();
}

HRESULT CDocHostSite::XDocHostUIHandler2::QueryInterface(REFIID riid, void ** ppvObj)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler2);

    return pThis->ExternalQueryInterface( &riid, ppvObj );
}

HRESULT CDocHostSite::XDocHostUIHandler2::GetHostInfo(DOCHOSTUIINFO *)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::ShowUI(DWORD /*dwID*/,
        IOleInPlaceActiveObject * /*pActiveObject*/,
        IOleCommandTarget * /*pCommandTarget*/,
        IOleInPlaceFrame * /*pFrame*/,
        IOleInPlaceUIWindow * /*pDoc*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::HideUI()
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::UpdateUI()
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::EnableModeless(BOOL /*fEnable*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::OnDocWindowActivate(BOOL /*fActivate*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::OnFrameWindowActivate(BOOL /*fActivate*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::ResizeBorder(LPCRECT /*prcBorder*/,
        IOleInPlaceUIWindow* /*pUIWindow*/,
        BOOL /*fRameWindow*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::ShowContextMenu(DWORD /*dwID*/,
        POINT* /*pptPosition*/,
        IUnknown* /*pCommandTarget*/,
        IDispatch* /*pDispatchObjectHit*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::TranslateAccelerator(LPMSG /*lpMsg*/,
        const GUID * /*pguidCmdGroup*/,
        DWORD /*nCmdID*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::GetOptionKeyPath(BSTR* /*pbstrKey*/, DWORD)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::GetDropTarget(IDropTarget * /*pDropTarget*/,
        IDropTarget ** /*ppDropTarget*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::GetExternal(IDispatch ** /*ppDispatch*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::TranslateUrl(DWORD /*dwTranslate*/,
        OLECHAR * /*pchURLIn*/,
        OLECHAR ** /*ppchURLOut*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::FilterDataObject(IDataObject * /*pDO*/,
        IDataObject ** /*ppDORet*/)
{
    ASSERT(FALSE);

    return S_FALSE;
}

HRESULT CDocHostSite::XDocHostUIHandler2::GetOverrideKeyPath(LPOLESTR * pchKey, DWORD dw)
{
    METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler2);
    return S_FALSE;
    //return pThis->m_pView->OnGetOverrideKeyPath( pchKey, dw );
}
#endif

// InternetSecurityManager Methods
HRESULT FAR EXPORT CDocHostSite::XInternetSecurityManager
::QueryInterface(REFIID riid, void** ppvObj)
{

    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj);
    return hr;
}

ULONG FAR EXPORT CDocHostSite::XInternetSecurityManager::AddRef()
{
    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CDocHostSite::XInternetSecurityManager::Release()
{

    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return pThis->ExternalRelease();
}

HRESULT CDocHostSite::XInternetSecurityManager
::SetSecuritySite (IInternetSecurityMgrSite *pSite)
{
    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return INET_E_DEFAULT_ACTION;
}

HRESULT CDocHostSite::XInternetSecurityManager
::GetSecuritySite(IInternetSecurityMgrSite **ppSite)
{

    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return INET_E_DEFAULT_ACTION;
}

HRESULT CDocHostSite::XInternetSecurityManager
::MapUrlToZone(LPCWSTR pwszUrl,DWORD *pdwZone,DWORD dwFlags)
{
    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return INET_E_DEFAULT_ACTION;
}


HRESULT  FAR EXPORT CDocHostSite::XInternetSecurityManager
										::GetSecurityId(LPCWSTR pwszUrl,
										BYTE *pbSecurityId,
										DWORD *pcbSecurityId, 
										DWORD dwReserved)
{

    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return INET_E_DEFAULT_ACTION;
}


STDMETHODIMP CDocHostSite::XInternetSecurityManager
::ProcessUrlAction(	/* [in] */ LPCWSTR pwszUrl,
                               /* [in] */ DWORD dwAction,
                               /* [size_is][out] */ BYTE __RPC_FAR *pPolicy,
                               /* [in] */ DWORD cbPolicy,
                               /* [in] */ BYTE __RPC_FAR *pContext,
                               /* [in] */ DWORD cbContext,
                               /* [in] */ DWORD dwFlags,
                               /* [in] */ DWORD dwReserved)
{

    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)

    DWORD dwPolicy=URLPOLICY_ALLOW;

    BOOL bNoActiveX=FALSE;
    BOOL bNoJava=FALSE;
    BOOL bNoScript=FALSE;
    BOOL bCrossData=FALSE;

    if (dwAction <= URLACTION_ACTIVEX_MAX && dwAction >= URLACTION_ACTIVEX_MIN)
        dwPolicy = bNoActiveX ? URLPOLICY_DISALLOW : URLPOLICY_ALLOW;
    else if ((dwAction <= URLACTION_JAVA_MAX && dwAction >= URLACTION_JAVA_MIN) ||
             URLACTION_HTML_JAVA_RUN == dwAction)
        if (bNoJava)
            dwPolicy = URLPOLICY_JAVA_PROHIBIT;
        else
            return INET_E_DEFAULT_ACTION;
    else if (dwAction <= URLACTION_SCRIPT_MAX && dwAction >= URLACTION_SCRIPT_MIN)
        dwPolicy = bNoScript ? URLPOLICY_DISALLOW : URLPOLICY_ALLOW;
// !! If the compiler can't find URLACTION_CROSS_DOMAIN_DATA, make sure you are building with
// !! the latest version of the IE headers -- URLMON.H specifically -- from MSDN Downloads for the
// !! Web Workshop or the Platform SDK
    else if (URLACTION_CROSS_DOMAIN_DATA == dwAction)
        dwPolicy = bCrossData ? URLPOLICY_ALLOW : URLPOLICY_DISALLOW;
    else
        return INET_E_DEFAULT_ACTION;

    if ( cbPolicy >= sizeof (DWORD))
    {
        *(DWORD*) pPolicy = dwPolicy;
        return S_OK;
    }
    else
    {
        return S_FALSE;
    }
}

HRESULT CDocHostSite::XInternetSecurityManager
::QueryCustomPolicy(LPCWSTR pwszUrl,
                    REFGUID guidKey,
                    BYTE **ppPolicy,
                    DWORD *pcbPolicy,
                    BYTE *pContext,
                    DWORD cbContext,
                    DWORD dwReserved)
{
    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return INET_E_DEFAULT_ACTION;
}

HRESULT CDocHostSite::XInternetSecurityManager
::SetZoneMapping(DWORD dwZone,
                 LPCWSTR lpszPattern,
                 DWORD dwFlags)
{
    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return INET_E_DEFAULT_ACTION;
}

HRESULT CDocHostSite::XInternetSecurityManager
::GetZoneMappings(DWORD dwZone,
                  IEnumString **ppenumString,
                  DWORD dwFlags)
{
    METHOD_PROLOGUE(CDocHostSite, InternetSecurityManager)
    return INET_E_DEFAULT_ACTION;
}


// ServiceProvider Methods
ULONG FAR EXPORT CDocHostSite::XServiceProvider::AddRef()
{
    METHOD_PROLOGUE(CDocHostSite, ServiceProvider)
    return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CDocHostSite::XServiceProvider::Release()
{
    METHOD_PROLOGUE(CDocHostSite, ServiceProvider)
    return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CDocHostSite::XServiceProvider
::QueryInterface(REFIID riid,
                 void** ppvObj)
{
    METHOD_PROLOGUE(CDocHostSite, ServiceProvider)
    HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj);
    return hr;
}
STDMETHODIMP CDocHostSite::XServiceProvider
								::QueryService(REFGUID guidService,  
												REFIID riid,
												void** ppvObject)
{

    if (guidService == SID_SInternetSecurityManager &&
            riid == IID_IInternetSecurityManager)
    {
        METHOD_PROLOGUE(CDocHostSite, ServiceProvider)
        HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObject);
        return hr;
    }
    else
    {
        *ppvObject = NULL;

    }
    return E_NOINTERFACE;
}

CMyOleDropTarget类的实现

其次,我们还需要实现一个类:CMyOleDropTarget

其申明如下:

#pragma once

#include <afxole.h>

// 拖动类型
#define DRAGTYPE_NONE			0
#define DRAGTYPE_FILE			1		// 文件

class CMyOleDropTarget : public COleDropTarget
{
    DECLARE_DYNAMIC(CMyOleDropTarget)
    DECLARE_INTERFACE_MAP()
    DECLARE_MESSAGE_MAP()

public:
    CMyOleDropTarget();
    virtual ~CMyOleDropTarget();

protected:
    LPDROPTARGET m_pIEDropTarget;

public:
    void SetIEDropTarget(LPDROPTARGET pDropTarget);
    void ReleaseIEDropTarget();

public:
    BEGIN_INTERFACE_PART(MyDropTarget, IDropTarget)
    INIT_INTERFACE_PART(CMyOleDropTarget, MyDropTarget)
    STDMETHOD(DragEnter)(LPDATAOBJECT, DWORD, POINTL, LPDWORD);
    STDMETHOD(DragOver)(DWORD, POINTL, LPDWORD);
    STDMETHOD(DragLeave)();
    STDMETHOD(Drop)(LPDATAOBJECT, DWORD, POINTL pt, LPDWORD);
    END_INTERFACE_PART(MyDropTarget)
};
实现部分为:

#include "stdafx.h"
#include "MyOleDropTarget.h"


IMPLEMENT_DYNAMIC(CMyOleDropTarget, COleDropTarget)

BEGIN_MESSAGE_MAP(CMyOleDropTarget, COleDropTarget)
END_MESSAGE_MAP()

BEGIN_INTERFACE_MAP(CMyOleDropTarget, COleDropTarget)
INTERFACE_PART(CMyOleDropTarget, IID_IDropTarget, MyDropTarget)
END_INTERFACE_MAP()

CMyOleDropTarget::CMyOleDropTarget()
{
    m_pIEDropTarget = NULL;
}

CMyOleDropTarget::~CMyOleDropTarget()
{
    ReleaseIEDropTarget();
}

void CMyOleDropTarget::SetIEDropTarget(LPDROPTARGET pDropTarget)
{
    if (m_pIEDropTarget)
        ReleaseIEDropTarget();
    m_pIEDropTarget = pDropTarget;
    m_pIEDropTarget->AddRef();
}

void CMyOleDropTarget::ReleaseIEDropTarget()
{
    if (!m_pIEDropTarget)
        return;
    m_pIEDropTarget->Release();
    m_pIEDropTarget = NULL;
}

STDMETHODIMP_(ULONG) CMyOleDropTarget::XMyDropTarget::AddRef()
{
    METHOD_PROLOGUE_EX_(CMyOleDropTarget, MyDropTarget)
    return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CMyOleDropTarget::XMyDropTarget::Release()
{
    METHOD_PROLOGUE_EX_(CMyOleDropTarget, MyDropTarget)
    return pThis->ExternalRelease();
}

STDMETHODIMP CMyOleDropTarget::XMyDropTarget::QueryInterface(
    REFIID iid, LPVOID* ppvObj)
{
    METHOD_PROLOGUE_EX_(CMyOleDropTarget, MyDropTarget)
    return pThis->ExternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP CMyOleDropTarget::XMyDropTarget::DragEnter(THIS_ LPDATAOBJECT lpDataObject,
        DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect)
{
    METHOD_PROLOGUE_EX(CMyOleDropTarget, MyDropTarget)
    ASSERT_VALID(pThis);

	if(pThis->m_pIEDropTarget)
		pThis->m_pIEDropTarget->DragEnter(lpDataObject, dwKeyState, pt, pdwEffect);
	return pThis->m_xDropTarget.DragEnter(lpDataObject, dwKeyState, pt, pdwEffect);
}

STDMETHODIMP CMyOleDropTarget::XMyDropTarget::DragOver(THIS_ DWORD dwKeyState,
        POINTL pt, LPDWORD pdwEffect)
{
    METHOD_PROLOGUE_EX(CMyOleDropTarget, MyDropTarget)
    ASSERT_VALID(pThis);

	if(pThis->m_pIEDropTarget)
		pThis->m_pIEDropTarget->DragOver(dwKeyState, pt, pdwEffect);
	return pThis->m_xDropTarget.DragOver(dwKeyState, pt, pdwEffect);
}

STDMETHODIMP CMyOleDropTarget::XMyDropTarget::DragLeave(THIS)
{
    METHOD_PROLOGUE_EX(CMyOleDropTarget, MyDropTarget)
    ASSERT_VALID(pThis);

	if(pThis->m_pIEDropTarget)
		pThis->m_pIEDropTarget->DragLeave();
	return pThis->m_xDropTarget.DragLeave();
}

STDMETHODIMP CMyOleDropTarget::XMyDropTarget::Drop(THIS_ LPDATAOBJECT lpDataObject,
        DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect)
{
    METHOD_PROLOGUE_EX(CMyOleDropTarget, MyDropTarget)
    ASSERT_VALID(pThis);

	if(pThis->m_pIEDropTarget)
		pThis->m_pIEDropTarget->Drop(lpDataObject, dwKeyState, pt, pdwEffect);
	return pThis->m_xDropTarget.Drop(lpDataObject, dwKeyState, pt, pdwEffect);
}

到目前为止,作为ActiveX小白的我,其实也没有彻底理解上述两个类的具体实现和作用,只知道其实现了对IE浏览器的定制和扩展。不过没关系,先用起来,后面慢慢理解。

对于相关知识,我转载了一篇文章:浏览器的定制和扩展,可能对我们的理解会有一定的帮助。

CBaseHtmlView中的相关函数实现

有了CDocHostSite 和 CMyOleDropTarget类。我们当然还需要在CBaseHtmlView中实现相应的函数。

我们定义了一个CMyOleDropTarget类的成员变量 m_DropTargat, 同时实现了5个函数,声明如下:

/******************************************
****** Javascript call MFC 相关函数********
*******************************************/
//JavaScript call MFC 的几个相关函数
CMyOleDropTarget m_DropTarget;
virtual BOOL CreateControlSite(COleControlContainer* pContainer, COleControlSite** ppSite, 
                               UINT nID, REFCLSID clsid);
virtual HRESULT OnGetDropTarget(LPDROPTARGET pDropTarget, LPDROPTARGET* ppDropTarget);
// 定制宿主信息
virtual HRESULT OnGetHostInfo(DOCHOSTUIINFO * pInfo);
// 设置脚本扩展
virtual HRESULT OnGetExternal(LPDISPATCH *lppDispatch);
// MesseBox
virtual HRESULT OnShowMessage(HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, 
                              DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT * plResult);

相关实现:

1、CreateControlSite:

BOOL CBaseHtmlView::CreateControlSite(COleControlContainer* pContainer, 
                                      COleControlSite** ppSite, UINT nID, REFCLSID clsid)
{
	*ppSite = new CDocHostSite(pContainer, this);// 创建自己的控制站点实例
	return (*ppSite) ? TRUE : FALSE;
}

2、OnGetDropTarget:

HRESULT CBaseHtmlView::OnGetDropTarget(LPDROPTARGET pDropTarget, LPDROPTARGET* ppDropTarget)
{
	m_DropTarget.SetIEDropTarget(pDropTarget);

	LPDROPTARGET pMyDropTarget;
	pMyDropTarget = (LPDROPTARGET)m_DropTarget.GetInterface(&IID_IDropTarget);
	if (pMyDropTarget)
	{
		*ppDropTarget = pMyDropTarget;
		pMyDropTarget->AddRef();
		return S_OK;
	}

	return S_FALSE;
}

3、OnGetHostInfo:

HRESULT CBaseHtmlView::OnGetHostInfo(DOCHOSTUIINFO * pInfo)
{
	pInfo->cbSize = sizeof(DOCHOSTUIINFO);
	pInfo->dwFlags = DOCHOSTUIFLAG_THEME | DOCHOSTUIFLAG_NO3DBORDER;
	pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;

	return S_OK;
}

4、OnGetExternal:

HRESULT CBaseHtmlView::OnGetExternal(LPDISPATCH *lppDispatch)
{
	*lppDispatch = GetIDispatch(TRUE);
	return S_OK;
}

5、OnShowMessage:

HRESULT CBaseHtmlView::OnShowMessage(HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT * plResult)
{
	// 窗口标题"Microsoft Internet Explorer"的资源标识
#define IDS_MESSAGE_BOX_TITLE 2213
	//载入Shdoclc.dll 和IE消息框标题字符串
	HINSTANCE hinstSHDOCLC = LoadLibrary(TEXT("SHDOCLC.DLL"));
	if (hinstSHDOCLC == NULL)
		return S_FALSE;

	CString strBuf, strCaption(lpstrCaption);
	strBuf.LoadString(hinstSHDOCLC, IDS_MESSAGE_BOX_TITLE);

	// 比较IE消息框标题字符串和lpstrCaption
	// 如果相同,用自定义标题替换
	if (strBuf == lpstrCaption)
		strCaption = "LHP HTMLVIEW";

	// 创建自己的消息框并且显示
	*plResult = MessageBox(CString(lpstrText), strCaption, dwType);

	//卸载Shdoclc.dll并且返回
	FreeLibrary(hinstSHDOCLC);

	return S_OK;
}


JavaScript消息的声明

在实现了上面的函数和类后,我们就可以利用MFC宏,通过消息传到,实现JavaScript调用MFC了。

首先在头文件中申明消息宏:

DECLARE_DISPATCH_MAP() // 构建dispatch映射表以暴露方法或属性

然后在CPP 中声明 消息宏:

BEGIN_DISPATCH_MAP(CDemoHtmlView, CBaseHtmlView)
	DISP_FUNCTION(CDemoHtmlView, "CloseWindow", CloseWindow, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION(CDemoHtmlView, "MinimizeWindow", MinimizeWindow, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION(CDemoHtmlView, "ClickCaption", ClickCaption, VT_EMPTY, VTS_WBSTR)
	DISP_FUNCTION(CDemoHtmlView, "slideIn", SetSlideIn, VT_EMPTY, VTS_I2)
	DISP_FUNCTION(CDemoHtmlView, "getLineData", getLineData, VT_EMPTY, VTS_WBSTR)
	DISP_FUNCTION(CDemoHtmlView, "getPieData", getPieData, VT_EMPTY, VTS_WBSTR)
	DISP_FUNCTION(CDemoHtmlView, "getThisDayData", getThisDayData, VT_EMPTY, VTS_WBSTR)
END_DISPATCH_MAP()

在DISP_FUNCTION中5个参数分别为:类名、JavaScript中调用MFC的函数名、响应函数名、返回类型、参数类型

以getLineData为例,JavaScript调用方式为:

window.external.getLineData(sendData);
其无返回值,传入参数为string,通常为JSON格式的字符串。

为此,我们需要实现一个响应函数:void getLineData(LPCTSTR lpszLineData);   //折线图

void CDemoHtmlView::getLineData(LPCTSTR lpszLineData)
{
	::PostMessage(GetParent()->GetSafeHwnd(), WM_MAINJS_LineData, (WPARAM)lpszLineData, NULL);
	return;
}
在此实现中,我们直接向主对话框发送自定义消息WM_MAINJS_LineData,让主对话框进行处理。考虑到阻塞和效率问题,通常情况下我们不直接在上面响应函数中直接实现响应,而是同时上面的消息形式,让后台去处理。为此,我们需要自己实现自定义消息的响应。这里就不进行介绍了。

一个小技巧

在上面,细心的读者可能发现,我们的类名不是CBaseHtmlView,变成CDemoHtmlView了,其实这里是我们的一个小技巧。

我们再写了一个CDemoHtmlView类,继承自CBaseHtmlView,我们将上述消息在此类中实现,同时我们也将主对话框类中定义的CBaseHtmlView变量该为此类变量。

类声明如下:

#pragma once

#ifdef _WIN32_WCE
#error "CHtmlView is not supported for Windows CE."
#endif 
#include "BaseHtmlView.h"
// CDemoHtmlView html view

class CDemoHtmlView : public CBaseHtmlView
{
	DECLARE_DYNCREATE(CDemoHtmlView)
	DECLARE_MESSAGE_MAP()
	DECLARE_DISPATCH_MAP() // 构建dispatch映射表以暴露方法或属性
public:
	CDemoHtmlView();           // protected constructor used by dynamic creation
	virtual ~CDemoHtmlView();

protected:
	virtual void OnInitialUpdate();
public:
	void CloseWindow();//关闭窗口
	void MinimizeWindow(); //最小化窗口
	void ClickCaption(LPCTSTR _bstr); //拖动窗口
	void SetSlideIn(short iShort); //右侧缩放

	void getLineData(LPCTSTR lpszLineData);   //折线图
	void getPieData(LPCTSTR lpszPieData); //饼状图
	void getThisDayData(LPCTSTR lpszDayData); //MONITOR页面数据渲染
	virtual void OnDocumentComplete(LPCTSTR lpszURL);
};



可以看到,我们除了实现JavaScript调用MFC的方法外,还特意继承了CBaseHtmlView的两个虚函数:OnInitialUpdate()  和 OnDocumentComplete 。

OnInitialUpdate() 函数 实现 html的加载, OnDocumentComplete函数 是加载完成后的通知。

这样我们就完全实现了对CBaseHtmlView的封装,以后添加相关html页面,我们也只需要添加一个继承自CBaseHtmlView 的具体类, 并实现上述两个函数 和 页面的响应函数就行,完全不用对CBaseHtmlView进行任何修改。

总结

好了,通过我的前两篇文章:MFC对话框里利用CHtmlView加载界面(一)————加载网页MFC对话框里利用CHtmlView加载界面(二)————MFC调用JaveScript  和本文的介绍,我们就实现了MFC 和 JavaScript的互相调用。 此外在MFC对话框里利用CHtmlView加载界面(四)————分层窗口设置中,我还介绍了如何去除MFC对话框背景,完全将HTML作为界面的方法。根据此四篇文章,我们就基本掌握了一种以MFC对话框为基础的,实现HTML界面和交互的方法。

本文的示范代码下载路径为:http://download.csdn.net/detail/qq_20828983/9900343



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值