![]()
Internet Explorerのコントロール(IEコントロール)ではスクリプトの実行や画像のダウンロードを抑えるダウンロードコントロール機能や、HTMLファイルの読み込みが終わったことを知らせるための各種イベント機能などを備えている。
ここではIEコントロールでスクリプトの実行などを抑える処理とダウンロード終了などのイベントを取得できるクラス「IDnpIESinkImpl」を作成した。
![]()
ここではテストのために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;
// }
//
// (...)
//};
