わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。

ブラウザからのイベントを取得する

IDispatchを継承したクラスを実装して、IConnectionPointのAdvise()関数で接続 すると、ブラウザからのイベントを取得する事ができます。

#include <tchar.h>
#include <shlobj.h>
#include <comdef.h>
#include <comutil.h>
#include <iostream>
#include <ExDispid.h>
using namespace std;




// I/F解放用マクロ
#define SAFE_RELEASE( p1 ) if ( p1 ) { p1->Release(); p1 = NULL; }



/*
	イベントをディスパッチさせる為にIDispatchから派生させたクラス
*/
class EventSink_CL : public IDispatch
{
	ULONG m_qRefCounter;

public:
	// コンストラクタ
	EventSink_CL()
		: m_qRefCounter( 1 )
	{
	}

	// デストラクタ
	virtual ~EventSink_CL()
	{
	}


	// AddRef
	virtual STDMETHODIMP_(ULONG) AddRef(void)
    {
		// 参照カウンタ+1
		return( ++m_qRefCounter );
    }

	// Release
	virtual STDMETHODIMP_(ULONG) Release(void)
	{
		// 参照カウンタ-1
		if ( 0 == --m_qRefCounter ) {

			// 参照カウンタが0になったら自身を破棄する
			delete this;
		}
		// 参照カウンタを返す
		return( m_qRefCounter );
    }

	// QueryInterface
	virtual STDMETHODIMP QueryInterface( REFIID riid, void **ppvOut )
	{
		HRESULT hResult = E_NOINTERFACE;

		// IID_IUnknownもしくはIID_IDispatchのI/Fは保有している
		if( IsEqualIID( riid, IID_IUnknown ) || IsEqualIID( riid, IID_IDispatch ) ) {

			// 参照カウンタ+1
			this->AddRef();

			// I/Fを返す。
			*ppvOut = reinterpret_cast<IDispatch*>( this );

			// 正常終了
			hResult = S_OK;

		} else {

			// 指定されたI/Fは保有していない。
			*ppvOut = NULL;
        }

		// 戻り値を返す
		return( hResult );
	}

	// GetTypeInfoCount
	virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount
	(
		/* [out] */	__RPC__out UINT *pctinfo
	)
	{
		return E_NOTIMPL;
	}

	// GetTypeInfo
	virtual HRESULT STDMETHODCALLTYPE GetTypeInfo
	(
		/* [in] */	UINT iTInfo,
		/* [in] */	LCID lcid,
		/* [out] */	__RPC__deref_out_opt ITypeInfo **ppTInfo
	)
	{
		return E_NOTIMPL;
	}

	// GetIDsOfNames
	virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames
	(
		/* [in] */				__RPC__in REFIID riid,
		/* [size_is][in] */		__RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
		/* [range][in] */		UINT cNames,
		/* [in] */				LCID lcid,
		/* [size_is][out] */	__RPC__out_ecount_full(cNames) DISPID *rgDispId
	)
	{
		return E_NOTIMPL;
	}

	// Invoke
	virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke
	(
		/* [in] */		DISPID dispIdMember,
		/* [in] */		REFIID riid,
		/* [in] */		LCID lcid,
		/* [in] */		WORD wFlags,
		/* [out][in] */	DISPPARAMS *pDispParams,
		/* [out] */		VARIANT *pVarResult,
		/* [out] */		EXCEPINFO *pExcepInfo,
		/* [out] */		UINT *puArgErr
	)
    {
        /*
			イベントを受信するとここが呼び出されます
				dispidMemberにイベントの種別が入ります。
				パラメータはpDispParamsに入ります。
		*/


		// イベント名の表示
		switch( dispIdMember ) {
		case DISPID_BEFORENAVIGATE:
			cout << "DISPID_BEFORENAVIGATE" << endl; break;
		case DISPID_NAVIGATECOMPLETE:
			cout << "DISPID_NAVIGATECOMPLETE" << endl; break;
		case DISPID_STATUSTEXTCHANGE:
			cout << "DISPID_STATUSTEXTCHANGE" << endl; break;
		case DISPID_QUIT:
			cout << "DISPID_QUIT" << endl; break;
		case DISPID_DOWNLOADCOMPLETE:
			cout << "DISPID_DOWNLOADCOMPLETE" << endl; break;
		case DISPID_COMMANDSTATECHANGE:
			cout << "DISPID_COMMANDSTATECHANGE" << endl; break;
		case DISPID_DOWNLOADBEGIN:
			cout << "DISPID_DOWNLOADBEGIN" << endl; break;
		case DISPID_NEWWINDOW:
			cout << "DISPID_NEWWINDOW" << endl; break;
		case DISPID_PROGRESSCHANGE:
			cout << "DISPID_PROGRESSCHANGE" << endl; break;
		case DISPID_WINDOWMOVE:
			cout << "DISPID_WINDOWMOVE" << endl; break;
		case DISPID_WINDOWRESIZE:
			cout << "DISPID_WINDOWRESIZE" << endl; break;
		case DISPID_WINDOWACTIVATE:
			cout << "DISPID_WINDOWACTIVATE" << endl; break;
		case DISPID_PROPERTYCHANGE:
			cout << "DISPID_PROPERTYCHANGE" << endl; break;
		case DISPID_TITLECHANGE:
			cout << "DISPID_TITLECHANGE" << endl; break;
		case DISPID_TITLEICONCHANGE:
			cout << "DISPID_TITLEICONCHANGE" << endl; break;
		case DISPID_FRAMEBEFORENAVIGATE:
			cout << "DISPID_FRAMEBEFORENAVIGATE" << endl; break;
		case DISPID_FRAMENAVIGATECOMPLETE:
			cout << "DISPID_FRAMENAVIGATECOMPLETE" << endl; break;
		case DISPID_FRAMENEWWINDOW:
			cout << "DISPID_FRAMENEWWINDOW" << endl; break;
		case DISPID_BEFORENAVIGATE2:
			cout << "DISPID_BEFORENAVIGATE2" << endl; break;
		case DISPID_NEWWINDOW2:
			cout << "DISPID_NEWWINDOW2" << endl; break;
		case DISPID_NAVIGATECOMPLETE2:
			cout << "DISPID_NAVIGATECOMPLETE2" << endl; break;
		case DISPID_ONQUIT:
			cout << "DISPID_ONQUIT" << endl; break;
		case DISPID_ONVISIBLE:
			cout << "DISPID_ONVISIBLE" << endl; break;
		case DISPID_ONTOOLBAR:
			cout << "DISPID_ONTOOLBAR" << endl; break;
		case DISPID_ONMENUBAR:
			cout << "DISPID_ONMENUBAR" << endl; break;
		case DISPID_ONSTATUSBAR:
			cout << "DISPID_ONSTATUSBAR" << endl; break;
		case DISPID_ONFULLSCREEN:
			cout << "DISPID_ONFULLSCREEN" << endl; break;
		case DISPID_DOCUMENTCOMPLETE:
			cout << "DISPID_DOCUMENTCOMPLETE" << endl; break;
		case DISPID_ONTHEATERMODE:
			cout << "DISPID_ONTHEATERMODE" << endl; break;
		case DISPID_ONADDRESSBAR:
			cout << "DISPID_ONADDRESSBAR" << endl; break;
		case DISPID_WINDOWSETRESIZABLE:
			cout << "DISPID_WINDOWSETRESIZABLE" << endl; break;
		case DISPID_WINDOWCLOSING:
			cout << "DISPID_WINDOWCLOSING" << endl; break;
		case DISPID_WINDOWSETLEFT:
			cout << "DISPID_WINDOWSETLEFT" << endl; break;
		case DISPID_WINDOWSETTOP:
			cout << "DISPID_WINDOWSETTOP" << endl; break;
		case DISPID_WINDOWSETWIDTH:
			cout << "DISPID_WINDOWSETWIDTH" << endl; break;
		case DISPID_WINDOWSETHEIGHT:
			cout << "DISPID_WINDOWSETHEIGHT" << endl; break;
		case DISPID_CLIENTTOHOSTWINDOW:
			cout << "DISPID_CLIENTTOHOSTWINDOW" << endl; break;
		case DISPID_SETSECURELOCKICON:
			cout << "DISPID_SETSECURELOCKICON" << endl; break;
		case DISPID_FILEDOWNLOAD:
			cout << "DISPID_FILEDOWNLOAD" << endl; break;
		case DISPID_NAVIGATEERROR:
			cout << "DISPID_NAVIGATEERROR" << endl; break;
		case DISPID_PRIVACYIMPACTEDSTATECHANGE:
			cout << "DISPID_PRIVACYIMPACTEDSTATECHANGE" << endl; break;
		case DISPID_NEWWINDOW3:
			cout << "DISPID_NEWWINDOW3" << endl; break;
		default:
			cout << "????????(" << dispIdMember << ")" << endl; break;
		}

		// 正常終了
		return S_OK;
	}
};



/*
	ブラウザからのイベントを取得する
*/
int _tmain
(
	  int argc
	, _TCHAR* argv[]
)
{
	int iRet = -1;

	// COMを初期化する
	CoInitialize( NULL );

	IWebBrowser2* pIE = NULL;

	// IWebBrowser2の取得
	CoCreateInstance(
			  CLSID_InternetExplorer
			, NULL
			, CLSCTX_LOCAL_SERVER
			, IID_IWebBrowser2
			, reinterpret_cast<VOID**>( &pIE )
		);

	// 取得できたかを確認する
	if ( NULL != pIE ){
		IDispatch*                 pDisp = NULL;
		IConnectionPointContainer* pCPC  = NULL;
		IConnectionPoint*          pCP   = NULL;
		DWORD dwCookie = 0L;

		EventSink_CL *opSink = new EventSink_CL();
		if ( NULL != opSink ) {

			// IDispatchの取得
			if ( S_OK != opSink->QueryInterface( IID_IDispatch
				, reinterpret_cast<void**>( &pDisp ) ) ) {
				goto err;
			}

			// 接続ポイントコンテナの取得
			if ( S_OK != pIE->QueryInterface( IID_IConnectionPointContainer
				, reinterpret_cast<LPVOID*>( &pCPC ) ) ) {
				goto err;
			}

			// 接続ポイント取得
			if ( S_OK != pCPC->FindConnectionPoint( DIID_DWebBrowserEvents2, &pCP ) ) {
				goto err;
			}

			// イベントシンクの接続
			if ( S_OK != pCP->Advise( reinterpret_cast<IUnknown*>( pDisp ), &dwCookie ) ) {
				goto err;
			}
		}

		// 指定したURIをオープン
		{
			_variant_t vEmpty;
			VariantInit( &vEmpty );

			// 指定したURIをオープン
			pIE->Navigate( _bstr_t( "http://www.wabiapp.com/" )
				, &vEmpty, &vEmpty, &vEmpty, &vEmpty );
		}

		// オープンが完了するまで待つ
		{
			VARIANT_BOOL bBusy;
			do
			{
				Sleep (500);

				// Busy状態の取得
				pIE->get_Busy ( &bBusy );

			} while ( bBusy );
		}

		/*
			初期状態が非表示となっているので表示する
			Navigateを呼び出す前にVisibleにしてもOKです。
		*/
		pIE->put_Visible( TRUE );

		// 入力を待たせる
		MessageBox( NULL, L"OKを押すと終了します。", L"メッセージ", MB_OK );

		// 正常終了
		iRet = 0;
err:
		// イベントシンクの接続解除
		if ( NULL != pCP && 0 != dwCookie ) pCP->Unadvise( dwCookie );

		// I/Fの破棄
		SAFE_RELEASE( pCPC );
		SAFE_RELEASE( pCP );
		SAFE_RELEASE( pDisp );

		// イベントシンクの破棄
		delete opSink;

		// ブラウザを閉じる
		if ( NULL != pIE ) pIE->Quit();
	}

	// IWebBrowser2の解放
	SAFE_RELEASE( pIE );

	// COMの使用終了
	CoUninitialize();

	// 正常終了
	return( iRet );
}



実行結果








わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。