Skip to content

실행중인 인터넷 익스플로어 제어하기

by Dog.Foot.Life on December 1st, 2010

이거, 간단치 않았던 작업이다. 열려있는 인터넷 익스플로어(이하 IE)를 제어해야 했다. 하다 보니, 이런걸 요청 받기도 하고 또, 겨우겨우 구현하기도 한다. 최단로(路)인지는 모르겠지만, 어쨌든 길은 길이다.

IE::_FindWindow(const TCHAR* tszSubWindowText)는 IE의 윈도우타이틀을 검색해서 핸들을 구한다. IE::Back()함수와 IE::Navigate()함수는 모두 윈도우 핸들을 찾기 위한 윈도우 타이틀을 인자로 요구하며, 각각, IE의 뒤로 가기와 URL이동을 구현한다.

이 코드는 oleacc.lib가 필요하며, Window XP에서 테스트 되었다.

class IE
{
public:
	static void	Back(const TCHAR* tszSubWindowText);
	static void	Navigate(const TCHAR* tszSubWindowText, const TCHAR* tszDestUrl);
private:
	IE()
	{}

	// Find Explorer_Server Window - subfunction of _Findwindow()
	static HWND	_Find_Explorer_Server(HWND hParentWnd, HWND hChildWnd);
	// Find IE Window
	static HWND	_FindWindow(const TCHAR* tszSubWindowText);
	static HWND	_FindWindowWithSubWindowText(const TCHAR* tszSubWindowText);

private:
	static HWND	m_hWnd;
};// class IE

HWND IE::_Find_Explorer_Server(HWND hParentWnd, HWND hChildWnd)
{
	if (hParentWnd == 0 || hChildWnd == 0)	return 0;

	TCHAR	tszClassName[1024]	= {0, };
	::GetClassName(hChildWnd, tszClassName, 1024);

	if (tstring(tszClassName) == _T("Internet Explorer_Server"))	return hChildWnd;

	HWND	hRetWnd	= _Find_Explorer_Server(hChildWnd, ::FindWindowEx(hChildWnd, 0, 0, 0));
	if (hRetWnd != 0)	return hRetWnd;

	return _Find_Explorer_Server(hParentWnd, ::FindWindowEx(hParentWnd, hChildWnd, 0, 0));
}

HWND IE::_FindWindow(const TCHAR* tszSubWindowText)
{
	HWND	hWnd	= _FindWindowWithSubWindowText(tszSubWindowText);
	return _Find_Explorer_Server(hWnd, ::FindWindowEx(hWnd, 0, 0, 0));
}

HWND IE::_FindWindowWithSubWindowText(const TCHAR* tszSubWindowText)
{
	HWND	hWnd	= 0;

	while (hWnd	= ::FindWindowEx(0, hWnd, _T("IEFrame"), 0))
	{
		TCHAR	tszWindowText[1024]	= {0, };
		::GetWindowText(hWnd, tszWindowText, 1024);
		size_t	pos	= tstring(tszWindowText).find(tszSubWindowText);
		if (pos != tstring::npos)	return hWnd;
	}

	return 0;
}

void IE::Back(const TCHAR* tszSubWindowText)
{
	m_hWnd	= _FindWindowWithSubWindowText(tszSubWindowText);

	if (m_hWnd)
	{
		::SetForegroundWindow(m_hWnd);

		m_hWnd	= _FindWindow(tszSubWindowText);

		HRESULT hr;

		if (FAILED(hr = CoInitialize(NULL)))	return;

		LRESULT	lRes;
		UINT	nMsg	= ::RegisterWindowMessage(_T("WM_HTML_GETOBJECT"));
		::SendMessageTimeout(m_hWnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes);
		CComPtr<IHTMLDocument2>		spDoc;
		CComPtr<IHTMLWindow2>		spWnd2;
		CComPtr<IServiceProvider>	spServiceProv;

		hr	= ::ObjectFromLresult(lRes, IID_IHTMLDocument2, 0, (void**)&spDoc);
		if (SUCCEEDED(hr))
		{
			hr	= spDoc->get_parentWindow((IHTMLWindow2**)&spWnd2);
			if (SUCCEEDED(hr))
			{
				hr	= spWnd2->QueryInterface(IID_IServiceProvider, (void**)&spServiceProv);
				if (SUCCEEDED(hr))
				{
					IWebBrowser2*	pWebBrowser2	= 0;
					hr	= spServiceProv->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&pWebBrowser2);
					hr	= pWebBrowser2->GoBack();
					pWebBrowser2->Release();

					spServiceProv.Release();
				}

				spWnd2.Release();
			}

			spDoc.Release();
		}

		CoUninitialize();
	}
}

void IE::Navigate(const TCHAR* tszSubWindowText, const TCHAR* tszDestUrl)
{
	m_hWnd	= _FindWindowWithSubWindowText(tszSubWindowText);

	if (m_hWnd)
	{
		::SetForegroundWindow(m_hWnd);

		m_hWnd	= _FindWindow(tszSubWindowText);

		HRESULT hr;

		if (FAILED(hr = CoInitialize(NULL)))	return;

		LRESULT	lRes;
		UINT	nMsg	= ::RegisterWindowMessage(_T("WM_HTML_GETOBJECT"));
		::SendMessageTimeout(m_hWnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes);
		CComPtr<IHTMLDocument2>		spDoc;
		CComPtr<IHTMLWindow2>		spWnd2;
		CComPtr<IServiceProvider>	spServiceProv;

		hr	= ::ObjectFromLresult(lRes, IID_IHTMLDocument2, 0, (void**)&spDoc);
		if (SUCCEEDED(hr))
		{
			hr	= spDoc->get_parentWindow((IHTMLWindow2**)&spWnd2);
			if (SUCCEEDED(hr))
			{
				hr	= spWnd2->QueryInterface(IID_IServiceProvider, (void**)&spServiceProv);
				if (SUCCEEDED(hr))
				{
					IWebBrowser2*	pWebBrowser2	= 0;
					hr	= spServiceProv->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&pWebBrowser2);

					CComVariant	v;
					CComBSTR	url(tszDestUrl);
					hr	= pWebBrowser2->Navigate(url, &v, &v, &v, &v);

					pWebBrowser2->Release();

					spServiceProv.Release();
				}

				spWnd2.Release();
			}

			spDoc.Release();
		}

		CoUninitialize();
	}
}

근데…, 이걸 어디에 쓰냐고?

쓸 데가 있더이다~

From → All, Dog

No comments yet

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS