第18回 アドレスバーに自動で現在のURLを表示する (タブブラウザーを作る)

tabbrowser66.gif
今までアドレスバーはURLを入力して開くというアドレスバー→タブ方向の一方的な機能しか実装されていなかった。Internet Explorerなどのアドレスバーではリンクのクリックなどにより読み込まれたホームページのURLが自動でアドレスバーに表示され、アドレスバーとタブが双方向にアクセスし合っている。

今回はタブ内で読み込まれたURLをアドレスバーに表示する機能を実装する。まずはURL変更をメインウインドウに知らせるための独自メッセージをstdafx.h内に定義する。
#define	WM_DNP_CHANGEADDRESS	(WM_APP + 3)		//■追加

tabbrowser67.gif そして定義した独自メッセージハンドラをMainFrm.h内に書く。ここでは(あまりやりたくはないのだが)直接アドレスバーへSetWindowTextでURLを書き込むことにした。
	BEGIN_MSG_MAP(CMainFrame)
		MESSAGE_HANDLER(WM_DNP_CREATENEWTAB, OnDnpCreateNewTab)
		MESSAGE_HANDLER(WM_DNP_CHANGEFOCUS, OnDnpChangeFocus)
		MESSAGE_HANDLER(WM_DNP_CHANGEADDRESS, OnDnpChangeAddress)		//■追加
		NOTIFY_CODE_HANDLER(CBEN_ENDEDIT, OnAddressbarEnter)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
		COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
		COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
		COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
		COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
		COMMAND_ID_HANDLER(ID_WINDOW_CLOSE, OnWindowClose)
		COMMAND_ID_HANDLER(ID_WINDOW_CLOSE_ALL, OnWindowCloseAll)
		COMMAND_RANGE_HANDLER(ID_WINDOW_TABFIRST, ID_WINDOW_TABLAST, OnWindowActivate)
		COMMAND_ID_HANDLER(ID_IE_BACK, OnIECommand)
		COMMAND_ID_HANDLER(ID_IE_NEXT, OnIECommand)
		COMMAND_ID_HANDLER(ID_IE_STOP, OnIECommand)
		COMMAND_ID_HANDLER(ID_IE_REFRESH, OnIECommand)
		COMMAND_ID_HANDLER(ID_IE_ADDFAVORITE, OnIEAddFavorite)
		COMMAND_ID_HANDLER(ID_IE_ORGANIZE_FAVORITE, OnIEOrganizeFavorite)
		NOTIFY_CODE_HANDLER(TBVN_CONTEXTMENU, OnTabContextMenu)
		MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
		COMMAND_RANGE_HANDLER(ID_FAVORITE_FIRST,ID_FAVORITE_LAST,OnFavorite)
		CHAIN_MSG_MAP_MEMBER(_cFovMenu)
		CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
		CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
	END_MSG_MAP()


	//■追加
	//アドレスバー表示用URLの変更処理
	//アクティブなタブのIEでURL変更があったときにメッセージが届く
	LRESULT OnDnpChangeAddress(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		LPCTSTR		pszURL = (LPCTSTR)wParam;

		if(pszURL == NULL)
			return	0;

		_wndAddressBar.SetWindowText(pszURL);

		return	0;
	}

tabbrowser68.gif
さらにビュークラスにIEコントロールからのイベントを受信して、URL変更をメインウインドウへ知らせる処理を追加する。

URLはIEコントロールからのOnNavigateComplete2イベントを受信したときにアドレスバーへ表示することにした。
	//■追加
	//メインウインドウへアドレス変更を通知する
	bool	NotifyChangeURL(LPCTSTR pszURL)
	{
		if(_pTabView == NULL)
			return	false;
		if(_pTabView->GetActivePage() != _pTabView->PageIndexFromHwnd(m_hWnd))
			return	false;			//このビューがアクティブでなければ処理しない

		GetTopLevelWindow().SendMessage(WM_DNP_CHANGEADDRESS,(WPARAM)pszURL);

		return	true;
	}

	void __stdcall OnNavigateComplete2(IDispatch *pDisp,VARIANT *pvURL)
	{
		//■処理内容実装
		if(pDisp != _pIWebBrowser2)
			return;			//フレームなどのイベントは無視

		NotifyChangeURL((CAtlString)pvURL->bstrVal);
	}

tabbrowser69.gif
これでビルド/実行するとアクティブタブでのページ切り替えを検出してアドレスバーのURLが自動的に変わるようになった。

まだこの状態だと、タブを切り替えたときにきちんとアドレスバーのURL表示が更新されない、次回はその点を修正する。


ちなみにInternet Exploreのアドレスバーではユーザーがアドレスを入力中(もしくは入力した形跡がある)ならアドレスバーの表示を変更しない、などの機能も備えているようだ。

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


カテゴリー「タブブラウザーを作る」 のエントリー