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

来源:互联网 发布:mac os x 升级系统 编辑:程序博客网 时间:2024/06/03 15:47

前言

在 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;// IDocHostShowUIprotected:    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)// IDocHostUIHandlerprotected:    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// IDocHostUIHandler2protected:    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 higherINTERFACE_PART(CDocHostSite, IID_IDocHostUIHandler2, DocHostUIHandler2)#endifINTERFACE_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 higherULONG 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 MethodsHRESULT 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 MethodsULONG 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_NONE0#define DRAGTYPE_FILE1// 文件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);// MesseBoxvirtual 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 viewclass CDemoHtmlView : public CBaseHtmlView{DECLARE_DYNCREATE(CDemoHtmlView)DECLARE_MESSAGE_MAP()DECLARE_DISPATCH_MAP() // 构建dispatch映射表以暴露方法或属性public:CDemoHtmlView();           // protected constructor used by dynamic creationvirtual ~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



原创粉丝点击