<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href='base.xsl'?>

<desc title="IEコンポーネントの使い方(IWebBrowser2)(ATL/WTL)">

	<source>
#include &lt;stdlib.h&gt;
#include &lt;windows.h&gt;
#include &lt;atlbase.h&gt;
#include &lt;atlhost.h&gt;

#define CLASS_NAME "IE Component Test"

HWND CreateIEWebBrowser( HWND parent, LPCTSTR url )
{
	RECT					rect;
	HWND					hwnd;
	CComPtr&lt;IUnknown&gt;		unknown;
	CComQIPtr&lt;IWebBrowser2&gt;	web2;
	CComVariant				no_use, navigate_url( url );

	if( !GetClientRect( parent, &amp;rect ) ) return NULL;
	if( !AtlAxWinInit() ) return NULL;

	hwnd = CreateWindow( "AtlAxWin71", "Shell.Explorer.2",
				WS_CHILD|WS_TABSTOP|WS_VISIBLE,
				rect.left, rect.top,
				abs( rect.right - rect.left ),
				abs( rect.bottom - rect.top ),
				parent, 0,
				(HINSTANCE)GetWindowLong( parent, GWL_HINSTANCE ),
				0
				);

	if( !hwnd ) return NULL;
	if( !url ) return hwnd;

	if( AtlAxGetControl( hwnd, &amp;unknown ) != S_OK ) return NULL;
	web2 = unknown;
	web2-&gt;Navigate2( &amp;navigate_url, &amp;no_use, &amp;no_use, &amp;no_use, &amp;no_use );
	return hwnd;
}

LRESULT CALLBACK WinProc( HWND h, UINT m, WPARAM w, LPARAM l )
{
	switch(m)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc( h, m, w, l );
}

int WINAPI WinMain( HINSTANCE hinst, HINSTANCE, LPSTR, int )
{
	GUID		guid;
	CComModule	module;	//WTL7.0以降ならこれでＯＫ
	WNDCLASS	wc;
	HWND		hwnd;
	MSG			msg;

	memset( &amp;wc, 0, sizeof(wc) );
	wc.hbrBackground	= (HBRUSH)GetStockObject( WHITE_BRUSH );
	wc.hCursor			= LoadCursor( NULL, IDC_ARROW );
	wc.hIcon			= LoadIcon( NULL, IDI_WINLOGO );
	wc.hInstance		= hinst;
	wc.lpfnWndProc		= WinProc;
	wc.lpszClassName	= CLASS_NAME;

	if( !RegisterClass( &amp;wc ) ) return 1;

	hwnd = CreateWindow( CLASS_NAME, "Web Browser Sample",
				WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_VISIBLE,
				0, 0, 800, 600, 0, 0, hinst, 0
				);

	//Init()する場所はAtlAxWinInit()関数を呼ぶ前なら良いらしい。
	//CreateIEWebBrowser()関数内で実行したらアサートに引っかかった。
	//ということは、WinMain()関数内でないとダメ？？？
	module.Init( 0, hinst, &amp;guid );

	CreateIEWebBrowser( hwnd, "http://www.yahoo.co.jp/" );

	while( GetMessage( &amp;msg, 0, 0, 0 ) &gt; 0 )
	{
		DispatchMessage( &amp;msg );
	}

	module.Term();
	return 0;
}
	</source>

	<r/>

	私は ATL, WTL, COM についての十分な知識がありません。<r/>
	間違いなどありましたら、ご指摘頂ければ幸いです。<r/>

	<block>
		<image file='mail.png' width="204" height="19" alt="メールアドレス"/>
	</block>

	参考にしたサイト
	<list>
		<item>
			<link url='http://ja.wikipedia.org/wiki/IE%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6'>IEコンポーネントブラウザ</link>
		</item>
		<item>
			<link url='http://codezine.jp/a/article/aid/178.aspx'>ATL/WTLプログラミング 1：ATL/WTLの概要と基本</link>
		</item>
		<item>
			<link url='http://www.noppi.jp/diary/?date=20041218'>めも日記(2004-12-18)</link><r/>
			WTL7x で
			ATLASSERT(!InlineIsEqualGUID(*m_plibid,GUID_NULL) &amp;&amp; "Did you forget to pass the LIBID to CComModule::Init?");
			というアサートが出る現象についての解決策が書かれています。
		</item>
		<item>
			<link url='http://home.att.ne.jp/banana/akatsuki/doc/atlwtl/'>ATL/WTL</link>
		</item>
		<item>
			メモリ管理クラス(ATL)
			<list>
				<item>
					<link url='http://msdn.microsoft.com/ja-jp/library/44yh1z4f(VS.80).aspx'>http://msdn.microsoft.com/ja-jp/library/44yh1z4f(VS.80).aspx</link>
				</item>
			</list>
		</item>
		<item>
			CComPtr と CComQIPtr の違いについて
			<list>
				<item>
					<link url='http://diarynote.jp/d/41486/200502.html'>My life your melody.</link>
				</item>
			</list>
		</item>
	</list>

	IEコンポーネントの扱い方については、
	下記のサイトをご覧いただければ事足りてしまうかも知れません。

	<list>
		<item>
			<link url='http://www.nitoyon.com/vc/tips/ie_component.htm'>IEコンポーネントの使い方[VC++の使い方]</link><r/>
		</item>
	</list>

	IEコンポーネントを利用するにあたって、
	VC++ のバージョンや、インストールしている WTL のバージョンによって、
	変更が必要になる部分があります。<r/>
	私がサンプルを作成した環境は以下の通りです。

	<list>
		<item>
			Windows XP Home Edition Version 2002 Service Pack 2
			<list>
				<item>Windows Update は毎回行っています。</item>
			</list>
		</item>
		<item>
			Microsoft Development Environment 2003 Version 7.1.6030
		</item>
		<item>
			Microsoft .NET Framework 1.1 バージョン 1.1.4322 SP1
		</item>
		<item>
			Microsoft Visual C++ .NET
		</item>
		<item>
			Microsoft Visual Studio .NET 2003 Service Pack 1
		</item>
		<item>
			Internet Explorer 7 バージョン 7.0.5730.13
		</item>
	</list>

	プロジェクトの設定

	<block>

		私の環境ではデフォルトのままで動作しました。<r/>
		ATL についても「ATL を使用しない」という設定のままです。

	</block>

	CComModule について

	<block>

		CComModule は WTL7.0 以降であれば、
		グローバル変数にする必要はないそうです。<r/>
		サンプルソースは WTL7.1 用です。<r/>

		<r/>

		module.Init() は、どうも WinMain() 関数内で呼ばなければならないようです。<r/>
		CreateIEWebBrowser() 関数内で呼び出すようにしたら、
		コンパイルとリンクは通りましたが、
		実行時にアサートにひっかかりました。<r/>

		<r/>

		VC++6.0 での記述方法は、前述したサイトに書かれているので省略します。<r/>

	</block>

	CreateIEWebBrowser() について

	<block>

		この関数は親ウィンドウのハンドルと、
		表示するウェブサイトのＵＲＬを受け取って、
		親ウィンドウのクライアント領域いっぱいに、
		IEのウェブブラウザを表示させる関数です。<r/>
		ウェブブラウザの作成に成功したら、そのウィンドウハンドルを返します。<r/>
		失敗時は NULL を返します。<r/>

		<r/>

		引数の説明
		<list>
			<item>
				parent<r/>
				親ウィンドウのハンドル
			</item>
			<item>
				url<r/>
				表示するウェブサイトのＵＲＬ<r/>
				NULL 指定時はウェブブラウザの作成のみ行い、
				ウェブサイトは表示しません。
			</item>
		</list>

		関数内の処理の捕捉説明
		<block>

			<font bold="yes">if( !AtlAxWinInit() ) return NULL;</font>

			<block>

				AtlAxWinInit() は、
				ATLを使ってIEのウェブブラウザを作成する前に必ず実行します。<r/>

			</block>

			<font bold="yes">hwnd = CreateWindow( "AtlAxWin71", "Shell.Explorer.2",</font>

			<block>

				"AtlAxWin71" は、WTL7x より前なら "AtlAxWin"、WTL8x 以降なら "AtlAxWin80"
				を指定するようです。<r/>
				現在 SourceForge でダウンロード可能な WTL7.5 の場合は、
				おそらく "AtlAxWin75" と指定します（動作検証はしてないので、
				間違っている可能性があります）。<r/>

				<r/>

				"Shell.Explorer.2" は固定です。<r/>
				IEコンポーネントを使う場合は必ずこのように指定します。<r/>

			</block>

		</block>

	</block>

	IEコンポーネントの機能を使う
	<block>

		IEウェブブラウザを作成したウィンドウのハンドルがあれば、
		IEコンポーネント(IWebBrowser2)の機能(メソッド)を呼び出すことができます。<r/>

		<r/>

		機能の呼び出し方
		<source>
HWND browser = CreateIEWebBrowser( hwnd_parent, NULL );
CComPtr&lt;IUnknown&gt;       unknown;
CComQIPtr&lt;IWebBrowser2&gt; web2;
if( AtlAxGetControl( browser, &amp;unknown ) == S_OK )
{
	web2 = unknown;
	web2-&gt;何かのメソッド;
}
		</source>

		<r/>

		どんな機能があるかの説明は、以下のサイトにおまかせします。

		<list>
			<item>
				MSDN IWebBrowser2 Interface<r/>
				<link url='http://msdn.microsoft.com/en-us/library/aa752127(VS.85).aspx'>http://msdn.microsoft.com/en-us/library/aa752127(VS.85).aspx</link>
			</item>
			<item>
				インターフェース IWebBrowser2(Java用)<r/>
				<link url='http://www.k-nextage.co.jp/ame/soft/wfc/htmldoc/com.ms.wfc.html.om/com/ms/wfc/html/om/shdocvw/IWebBrowser2.html'>http://www.k-nextage.co.jp/ame/soft/wfc/htmldoc/com.ms.wfc.html.om/com/ms/wfc/html/om/shdocvw/IWebBrowser2.html</link>
			</item>
		</list>

	</block>

</desc>

