IEコントロールからのイベントを処理する

test119_01.gif
Internet Explorerのコントロール(IEコントロール)ではスクリプトの実行や画像のダウンロードを抑えるダウンロードコントロール機能や、HTMLファイルの読み込みが終わったことを知らせるための各種イベント機能などを備えている。

ここではIEコントロールでスクリプトの実行などを抑える処理とダウンロード終了などのイベントを取得できるクラス「IDnpIESinkImpl」を作成した。

test119_02.gif
ここではテストのためにATL/WTLアプリケーションウイザードでSDIアプリケーションを作成した。その際にビューウインドウの形式で「HTMLページ」を指定することでビューがIEコントロールになっているウインドウのプロジェクトを作成し、そのIEコントロールからのイベントを処理した。

ビューからIEコントロールを取得するにはQueryControlを利用する。

■自動生成された「プロジェクト名View.h」ファイルの先頭に以下のHTMLイベント処理用のクラスを追加する。自分の好みに応じた処理をしたい場合はこの実装を変える。

#include "DnpIESinkImpl.h"



//
//	イベント処理用クラス
//
class ATL_NO_VTABLE CIESink : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public IOleClientSite,
	public IDispatch,
	public IDnpIESinkImpl
{
public:
	CIESink()
	{
	}

	BEGIN_COM_MAP(CIESink)
		COM_INTERFACE_ENTRY(IDnpIESink)
		COM_INTERFACE_ENTRY(IOleClientSite)
		COM_INTERFACE_ENTRY(IDispatch)
	END_COM_MAP()

	DECLARE_PROTECT_FINAL_CONSTRUCT()


	////////////////////////////
	//	IDispatch;
	//
	STDMETHOD(Invoke)(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
	{
		if(dispIdMember == DISPID_AMBIENT_DLCONTROL)
		{
			//ダウンロードコントロール設定

			//ATLTRACE("DISPID_AMBIENT_DLCONTROL\n");
			V_VT(pVarResult) = VT_I4;
			V_I4(pVarResult) = _nAmbientPropertyFlags;
			return	S_OK;
		}


		if(dispIdMember == DISPID_DOWNLOADCOMPLETE)
		{
			ATLTRACE("DISPID_DOWNLOADCOMPLETE\n");
			return	S_OK;
		}
		if(dispIdMember == DISPID_NAVIGATECOMPLETE)
		{
			ATLTRACE("DISPID_NAVIGATECOMPLETE\n");
			return	S_OK;
		}
		if(dispIdMember == DISPID_NAVIGATECOMPLETE2)
		{
			ATLTRACE("DISPID_NAVIGATECOMPLETE2\n");
			return	S_OK;
		}
		if(dispIdMember == DISPID_DOCUMENTCOMPLETE)
		{
			::MessageBox(NULL,_T("HTMLの読み込みが終わりました"),_T(""),MB_OK);
			ATLTRACE("DISPID_DOCUMENTCOMPLETE\n");
			return	S_OK;
		}
		if(dispIdMember == DISPID_NAVIGATEERROR)
		{
			ATLTRACE("DISPID_NAVIGATEERROR\n");
			return	S_OK;
		}

		return	S_OK;
	}
	STDMETHOD(GetTypeInfoCount)(UINT *pctinfo)
	{
		*pctinfo = 0;
		return	S_OK;
	}
	STDMETHOD(GetTypeInfo)(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)					{	return	E_NOTIMPL;		}
	STDMETHOD(GetIDsOfNames)(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId)	{	return	E_NOTIMPL;		}




	///////////////////////////////////
	//	IOleControlSite
	//
	STDMETHOD(GetMoniker)(DWORD dwAssign,DWORD dwWhichMoniker,IMoniker **ppmk)		{	return	E_NOTIMPL;		}
	STDMETHOD(SaveObject)(void)							{	return	E_NOTIMPL;		}
	STDMETHOD(GetContainer)(IOleContainer **ppContainer){	return	E_NOTIMPL;		}
	STDMETHOD(ShowObject)(void)							{	return	E_NOTIMPL;		}
	STDMETHOD(OnShowWindow)(BOOL fShow)					{	return	E_NOTIMPL;		}
	STDMETHOD(RequestNewObjectLayout)(void)				{	return	E_NOTIMPL;		}
};

■ビュークラスの中にIEへのコネクト処理を追加する。この処理を行うことでIEコントロールで発生したイベントを取得できる。ここではウインドウ作成時と破壊時にそれぞれコネクト、ディスコネクトしている

	BEGIN_MSG_MAP(CTest119View)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
	END_MSG_MAP()


	CComPtr<IDnpIESink>		_pIESink;


	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT	ret;

		CComPtr<IWebBrowser2>	pIWebBrowser2;

		ret = DefWindowProc(uMsg,wParam,lParam);

		QueryControl(&pIWebBrowser2);

		if(pIWebBrowser2)
		{
			HRESULT	hr;

			_pIESink = new CComObject<CIESink>;

			hr = _pIESink->Init();
			if(SUCCEEDED(hr))
				hr = _pIESink->SetIE(pIWebBrowser2);		//IEのセット
			if(SUCCEEDED(hr))
				hr = _pIESink->Advice();					//接続

			//ダウンロードコントロール設定
			if(SUCCEEDED(hr))
				hr = _pIESink->AmbientPropertyChange(DLCTL_DOWNLOADONLY | DLCTL_NO_SCRIPTS | DLCTL_NO_JAVA | DLCTL_NO_DLACTIVEXCTLS | DLCTL_NO_RUNACTIVEXCTLS);
		}

		return	ret;
	}


	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;

		if(_pIESink)
			_pIESink->Init();

		return	0;
	}

■以下のソースコードをファイル名「DnpIESinkImpl.h」として保存する

#pragma	once


#include "mshtml.h"
#include "mshtmdid.h"
#include "Exdisp.h"
#include "Exdispid.h"


//
//	Internet Explorerのイベント処理&ダウンロードコントロール用クラス群
//
//	使用例はこのファイル末尾
//





MIDL_INTERFACE("55647A04-86A4-436d-BF23-154F75582E8A")
IDnpIESink : public IUnknown
{
public:
	STDMETHOD(Init)(void) = 0;
	STDMETHOD(SetIE)(IDispatch* pWebBrowser) = 0;
	STDMETHOD(Advice)(void) = 0;
	STDMETHOD(Unadvice)(void) = 0;
	STDMETHOD(AmbientPropertyChange)(LONG nFlags) = 0;
};




class ATL_NO_VTABLE IDnpIESinkImpl	: public IDnpIESink
{
public:
	IDnpIESinkImpl()
	{
		Init();
	}

	~IDnpIESinkImpl()
	{
		ATLASSERT(_pConnectionPoint == NULL);		//接続が解除されていない!
		Init();
	}

protected:
	DWORD		_dwCookie;
	LONG		_nAmbientPropertyFlags;
	CComPtr<IWebBrowser2>		_pWebBrowser2;
	CComPtr<IConnectionPoint>	_pConnectionPoint;

public:


	//
	//	クラスの初期化
	//
	STDMETHOD(Init)(void)
	{
		_nAmbientPropertyFlags = 0;

		if(_pConnectionPoint)
			Unadvice();

		if(_pWebBrowser2)
			_pWebBrowser2 = NULL;

		_dwCookie = 0;

		return	S_OK;
	}



	//
	//	Internet Explorerの設定
	//
	STDMETHOD(SetIE)(IDispatch* pWebBrowser)
	{
		ATLASSERT(pWebBrowser);
		if(pWebBrowser == NULL)
			return	E_FAIL;

		ATLASSERT(_pWebBrowser2 == NULL);
		if(_pWebBrowser2)
			return	E_FAIL;

		return	pWebBrowser->QueryInterface(IID_IWebBrowser2,(void**)&_pWebBrowser2);
	}



	//
	//	Internet Explorerとの接続
	//
	//	必ずUnadviceすること!
	//
	STDMETHOD(Advice)(void)
	{
		HRESULT	hr;

		CComPtr<IUnknown>	pUnknown;
		CComPtr<IConnectionPointContainer>	pConnectionPointContainer;

		ATLASSERT(_pConnectionPoint == NULL);		//接続済み
		ATLASSERT(_pWebBrowser2);
		if(_pWebBrowser2 == NULL)
			return	E_FAIL;


		QueryInterface(IID_IUnknown,(void**)&pUnknown);

		hr = E_FAIL;
		_dwCookie = 0;
		_pWebBrowser2->QueryInterface(&pConnectionPointContainer);
		if(pConnectionPointContainer)
		{
			_pConnectionPoint = NULL;
			pConnectionPointContainer->FindConnectionPoint(__uuidof(DWebBrowserEvents2),&_pConnectionPoint);
		}
		if(_pConnectionPoint)
			hr = _pConnectionPoint->Advise(pUnknown,&_dwCookie);

		return	hr;
	}



	//
	//	Internet Explorerとの接続解除
	//
	STDMETHOD(Unadvice)(void)
	{
		HRESULT	hr;

		if(_pConnectionPoint == NULL)
			return	E_FAIL;

		hr = _pConnectionPoint->Unadvise(_dwCookie);
		if(SUCCEEDED(hr))
		{
			_dwCookie = 0;
			_pConnectionPoint = NULL;
			return	S_OK;
		}

		return	E_FAIL;
	}



	//
	//	ダウンロードコントロールの設定
	//
	//
	//	nFlagsは以下のようなフラグ
	//		DLCTL_DOWNLOADONLY | DLCTL_NO_SCRIPTS | DLCTL_NO_JAVA | DLCTL_NO_DLACTIVEXCTLS | DLCTL_NO_RUNACTIVEXCTLS;
	//
	STDMETHOD(AmbientPropertyChange)(LONG nFlags)
	{
		HRESULT	hr;

		CComPtr<IOleControl>	pOleControl;
		CComPtr<IOleObject>		pOleObject;
		CComPtr<IOleClientSite>	pOleClientSite;

		hr = QueryInterface(IID_IOleClientSite,(void**)&pOleClientSite);
		if(pOleClientSite == NULL)
			return	E_FAIL;

		if(_pWebBrowser2 == NULL)
			return	E_FAIL;

		hr = _pWebBrowser2->QueryInterface(&pOleObject);
		if(pOleObject)
			hr = pOleObject->SetClientSite(pOleClientSite);

		if(SUCCEEDED(hr))
			hr = _pWebBrowser2->QueryInterface(&pOleControl);
		if(pOleControl)
		{
			_nAmbientPropertyFlags = nFlags;
			hr = pOleControl->OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL);
		}

		return	hr;
	}
};









//
//	使用例
//


//
////	イベント処理用クラス
////
//class ATL_NO_VTABLE CIESink : 
//	public CComObjectRootEx<CComSingleThreadModel>,
//	public IOleClientSite,
//	public IDispatch,
//	public IDnpIESinkImpl
//{
//public:
//	CIESink()
//	{
//	}
//
//	BEGIN_COM_MAP(CIESink)
//		COM_INTERFACE_ENTRY(IDnpIESink)
//		COM_INTERFACE_ENTRY(IOleClientSite)
//		COM_INTERFACE_ENTRY(IDispatch)
//	END_COM_MAP()
//
//	DECLARE_PROTECT_FINAL_CONSTRUCT()
//
//
//	////////////////////////////
//	//	IDispatch;
//	//
//	STDMETHOD(Invoke)(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
//	{
//		if(dispIdMember == DISPID_AMBIENT_DLCONTROL)
//		{
//			//ダウンロードコントロール設定
//
//			//ATLTRACE("DISPID_AMBIENT_DLCONTROL\n");
//			V_VT(pVarResult) = VT_I4;
//			V_I4(pVarResult) = _nAmbientPropertyFlags;
//			return	S_OK;
//		}
//
//
//		if(dispIdMember == DISPID_DOWNLOADCOMPLETE)
//		{
//			ATLTRACE("DISPID_DOWNLOADCOMPLETE\n");
//			return	S_OK;
//		}
//		if(dispIdMember == DISPID_NAVIGATECOMPLETE)
//		{
//			ATLTRACE("DISPID_NAVIGATECOMPLETE\n");
//			return	S_OK;
//		}
//		if(dispIdMember == DISPID_NAVIGATECOMPLETE2)
//		{
//			ATLTRACE("DISPID_NAVIGATECOMPLETE2\n");
//			return	S_OK;
//		}
//		if(dispIdMember == DISPID_DOCUMENTCOMPLETE)
//		{
//			ATLTRACE("DISPID_DOCUMENTCOMPLETE\n");
//			return	S_OK;
//		}
//		if(dispIdMember == DISPID_NAVIGATEERROR)
//		{
//			ATLTRACE("DISPID_NAVIGATEERROR\n");
//			return	S_OK;
//		}
//
//		return	S_OK;
//	}
//	STDMETHOD(GetTypeInfoCount)(UINT *pctinfo)
//	{
//		*pctinfo = 0;
//		return	S_OK;
//	}
//	STDMETHOD(GetTypeInfo)(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)					{	return	E_NOTIMPL;		}
//	STDMETHOD(GetIDsOfNames)(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId)	{	return	E_NOTIMPL;		}
//
//
//
//
//	///////////////////////////////////
//	//	IOleControlSite
//	//
//	STDMETHOD(GetMoniker)(DWORD dwAssign,DWORD dwWhichMoniker,IMoniker **ppmk)		{	return	E_NOTIMPL;		}
//	STDMETHOD(SaveObject)(void)							{	return	E_NOTIMPL;		}
//	STDMETHOD(GetContainer)(IOleContainer **ppContainer){	return	E_NOTIMPL;		}
//	STDMETHOD(ShowObject)(void)							{	return	E_NOTIMPL;		}
//	STDMETHOD(OnShowWindow)(BOOL fShow)					{	return	E_NOTIMPL;		}
//	STDMETHOD(RequestNewObjectLayout)(void)				{	return	E_NOTIMPL;		}
//};
//
//



////
////	ウインドウ内での使用
////
//class	CTestDlg : public CDialog
//{
//	CComPtr<IDnpIESink>		_pIESink;
//
//public:
//	(...)
//
//	~CTestDlg()
//	{
//		if(_pIESink)
//			_pIESink->Init();
//	}
//
//
//	BOOL	OnInitDialog(...)
//	{
//		(...)
//
//		HRESULT	hr;
//
//		_pIESink = new CComObject<CIESink>;
//
//		hr = _pIESink->Init();
//		if(SUCCEEDED(hr))
//			hr = _pIESink->SetIE(pWebBrowser2);			//IEのセット
//		if(SUCCEEDED(hr))
//			hr = _pIESink->Advice();					//接続
//
//		//ダウンロードコントロール設定
//		if(SUCCEEDED(hr))
//			hr = _pIESink->AmbientPropertyChange(DLCTL_DOWNLOADONLY | DLCTL_NO_SCRIPTS | DLCTL_NO_JAVA | DLCTL_NO_DLACTIVEXCTLS | DLCTL_NO_RUNACTIVEXCTLS);
//
//		(...)
//
//		return	TRUE;
//	}
//
//	(...)
//};


プロジェクトファイルをダウンロード


カテゴリー「Internet Explorer」 のエントリー