前言
在 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