IEを探し出してIHTMLDocument2を取得する

現在開いているInternet Explorerを探し出して、アクセスしているURLを表示する。
Internet Explorerのウインドウを探し出すにはEnumWindowsとEnumChildWindowsを利用する。そして求めたウインドウハンドルからCOMインターフェースを取得してURLを表示している。ここではIHTMLDocument2へのポインタを取得したが、これを用いればHTMLソースの取得から改変。新しいURLへのジャンプ…IE上での操作をほぼすべて行える。
またこの方法はIE6までの従来スタイルのIEからタブブラウザタイプのIE7にまで対応する。

依存環境:ATL
#include "atlstr.h"

#include "exdisp.h"
#include "mshtml.h"



//
//HWNDからIHTMLDocument2の取得(MSDN改変)
//
//HWNDは"Internet Explorer_Server"のウインドウハンドル
//bHwndIsServer==falseのときは"Shell DocObject View"のウインドウハンドルとして処理
//
bool	GetHTMLDocument2FromHWND(HWND hWnd,IHTMLDocument2** ppIHTMLDocument2,bool bHwndIsServer=true)
{
	HINSTANCE	hInst;
	LRESULT		lRes;
	UINT		nMsg;
	LRESULT		ret;

	LPFNOBJECTFROMLRESULT pfObjectFromLresult;

	if(ppIHTMLDocument2 == NULL || hWnd == NULL || ::IsWindow(hWnd) == FALSE)
		return	false;

	if(bHwndIsServer == false)
	{
		//"Shell DocObject View"へのハンドルとして処理
		hWnd = ::FindWindowEx(hWnd,NULL,_T("Internet Explorer_Server"),NULL);
		if(hWnd == NULL)
			return	false;
	}

	hInst = ::LoadLibrary(_T("OLEACC.DLL"));
	if(hInst == NULL)
		return	false;

	nMsg = ::RegisterWindowMessage(_T("WM_HTML_GETOBJECT"));
	ret = ::SendMessageTimeout(hWnd,nMsg,0,0,SMTO_ABORTIFHUNG,1000,(DWORD*)&lRes);
	if(ret == 0)
		return	false;

	pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress(hInst,"ObjectFromLresult");
	if(pfObjectFromLresult)
		(*pfObjectFromLresult)(lRes,IID_IHTMLDocument2,0,(void**)ppIHTMLDocument2);

	::FreeLibrary(hInst);

	return	*ppIHTMLDocument2 ? true : false;
}





class	CDnpEnumInternetExplore
{
	//
	//	EnumWindowsのコールバック関数
	//
	//※ユーザーは直接呼ばないこと!
	//
	static	BOOL	CALLBACK	EnumWindowsProc_(HWND hwnd,LPARAM lParam)
	{
		if(lParam == NULL)
			return	FALSE;
		return	((CDnpEnumInternetExplore*)lParam)->EnumWindowsProc(hwnd);
	}



	//
	//	EnumChildWindowsのコールバック関数
	//
	//※ユーザーは直接呼ばないこと!
	//
	static	BOOL CALLBACK	EnumChildProc_(HWND hwnd,LPARAM lParam)
	{
		if(lParam == NULL)
			return	FALSE;
		return	((CDnpEnumInternetExplore*)lParam)->EnumChildProc(hwnd);
	}
public:


	//
	//	列挙開始
	//
	bool	EnumStart(void)
	{
		BOOL	ret;

		ret = ::EnumWindows(EnumWindowsProc_,(LPARAM)this);

		return	ret ? true : false;
	}


	//
	//	EnumWindowsのコールバック実処理関数
	//
	//※ユーザーは直接呼ばないこと!
	//
	BOOL	EnumWindowsProc(HWND hwnd)
	{
		int		nRet;
		TCHAR	pszName[1024];

		//ウインドウクラスの取得
		nRet = ::GetClassName(hwnd,pszName,1024);
		if(nRet == 0)
			return	TRUE;

		//IEはクラス名が"IEFrame"
		nRet = ::_tcscmp(pszName,_T("IEFrame"));
		if(nRet != 0)
			return	TRUE;

		//子ウインドウの列挙方法
		::EnumChildWindows(hwnd,EnumChildProc_,(LPARAM)this);

		return	TRUE;
	}



	//
	//	EnumChildWindowsのコールバック実処理関数
	//
	//※ユーザーは直接呼ばないこと!
	//
	BOOL	EnumChildProc(HWND hwnd)
	{
		int		nRet;
		bool	ret;
		HRESULT	hr;
		BSTR	bstrURL;
		TCHAR	pszName[1024];
		IHTMLDocument2*	pIHTMLDocument2;

		//ウインドウクラスの取得
		nRet = ::GetClassName(hwnd,pszName,1024);
		if(nRet == 0)
			return	TRUE;

		//クラス名"Internet Explorer_Server"を取得
		nRet = ::_tcscmp(pszName,_T("Internet Explorer_Server"));
		if(nRet != 0)
			return	TRUE;

		//HWNDからIHTMLDocument2の取得
		pIHTMLDocument2 = NULL;
		ret = GetHTMLDocument2FromHWND(hwnd,&pIHTMLDocument2);
		if(ret == false || pIHTMLDocument2 == NULL)
			return	TRUE;

		//URL取得
		bstrURL = NULL;
		hr = pIHTMLDocument2->get_URL(&bstrURL);
		if(SUCCEEDED(hr))
		{
			CAtlString	strURL;

			//BSTRからCString(TCHAR)への変換
			strURL = (WCHAR*)bstrURL;
			::SysFreeString(bstrURL);

			//URL表示
			::MessageBox(NULL,strURL,_T(""),MB_OK);
		}

		pIHTMLDocument2->Release();

		return	TRUE;
	}

};




void	Test(void)
{
	::CoInitialize(NULL);

	CDnpEnumInternetExplore	cEnum;

	cEnum.EnumStart();

	::CoUninitialize();
}

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


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