第33回 ページエラー発生時にアイコンを表示する (タブブラウザーを作る)

tabbrowser132.gif
前回はステータスバーにアイコンを表示するテストを行った。今回はページにエラーが発生しているときのみアイコンが表示されるようにする。

まずビュークラスにエラーが発生したときにメインウインドウへそれを知らせる処理を追加する。 ここでは独自メッセージWM_DNP_SCRIPTERRORのWPARAMをエラー発生時TRUE、エラー解消時FALSEという意味付けを行い、メインウインドウへ送信するようにした。
	//■追加
	//エラー発生/解消時に呼ぶ
	//bError=trueならエラー発生
	void	SetErrorState(bool bError)
	{
		_bPageError = bError;			//エラーが発生したことを保持
		if(bError)
			ChangeStatusText(NULL);

		if(_pTabView == NULL || _pTabView->GetActivePage() != _pTabView->PageIndexFromHwnd(m_hWnd))
			return;			//このビューがアクティブでなければこれ以降処理しない

		//メインウインドウにエラー発生を通知
		GetTopLevelWindow().SendMessage(WM_DNP_SCRIPTERROR,(WPARAM)(bError ? TRUE : FALSE));
	}

	//■追加
	bool	IsPageError(void)
	{
		return	_bPageError;
	}



	LRESULT OnDnpScriptError(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		//■処理変更
		SetErrorState(true);
		return	0;
	}


	//最後にIEコントロールから受け取ったステータスバー用メッセージを返す
	void	GetLastStatusText(CAtlString& strText)
	{
		strText = _strLastStatusText;

		//表示する文字がないときで、現在ページにエラーがあればエラーメッセージを返す
		if(_bPageError && strText == _T(""))
			strText = _T("ページでエラーが発生しました。");
	}

	void __stdcall OnDownloadComplete()
	{
	}

	void __stdcall OnCommandStateChange(long lCommand,VARIANT_BOOL vbEnable)
	{
	}

	void __stdcall OnDownloadBegin(void)
	{
		SetErrorState(false);		//■変更 エラー情報をリセット
	}

tabbrowser131.gif WM_DNP_SCRIPTERRORのWPARAMに意味付けを追加してしまったので、直接は関係ないがスクリプト検出用のクラスの処理でもWPARAMがTRUEになるように変更しておく。
    STDMETHODIMP Exec( const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG* pvaIn, VARIANTARG* pvaOut)
    {
		//コマンドがスクリプトエラーを示すものなら、エラー表示を無効にする
		if(nCmdID == OLECMDID_SHOWSCRIPTERROR)
		{
			(*pvaOut).vt		= VT_BOOL;
			(*pvaOut).boolVal	= VARIANT_TRUE;

			if(_hWndNotify && ::IsWindow(_hWndNotify))
				::SendMessage(_hWndNotify,WM_DNP_SCRIPTERROR,(WPARAM)TRUE,NULL);		//■変更

			return S_OK;
		}

		return E_NOTIMPL;
    }

tabbrowser133.gif 忘れずにNavigateErrorイベント発生時の処理にもメインウインドウへ通知がいくように変更しておく。
	void __stdcall OnNavigateError(IDispatch *pDisp,VARIANT *vURL,VARIANT *vTargetFrameName,VARIANT *vStatusCode,VARIANT_BOOL *vbCancel)
	{
		SetErrorState(true);		//■変更 スクリプトエラー出なくてもエラーが発生したらtrueにする
	}

tabbrowser134.gif そしてメインウインドウ側でスクリプトエラーが処理されるようにメッセージハンドラを追加する。
	BEGIN_MSG_MAP(CMainFrame)
		MESSAGE_HANDLER(WM_DNP_CREATENEWTAB, OnDnpCreateNewTab)
		MESSAGE_HANDLER(WM_DNP_CHANGEFOCUS, OnDnpChangeFocus)
		MESSAGE_HANDLER(WM_DNP_CHANGEADDRESS, OnDnpChangeAddress)
		MESSAGE_HANDLER(WM_DNP_CHANGESTATUSTEXT, OnDnpChangeStatusText)
		MESSAGE_HANDLER(WM_DNP_CHANGEPROGRESS, OnDnpChangeProgress)
		MESSAGE_HANDLER(WM_DNP_SCRIPTERROR, OnDnpScriptError)		//■追加
		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_ID_HANDLER(ID_FILE_PRINT, OnFileCommand)
		COMMAND_ID_HANDLER(ID_FILE_PRINT_PREVIEW, OnFileCommand)
		COMMAND_ID_HANDLER(ID_FILE_PRINT_SETUP, OnFileCommand)
		COMMAND_ID_HANDLER(ID_EDIT_COPY, OnFileCommand)
		COMMAND_ID_HANDLER(ID_EDIT_CUT, OnFileCommand)
		COMMAND_ID_HANDLER(ID_EDIT_PASTE, OnFileCommand)
		COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, OnFileCommand)
		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)
		NOTIFY_CODE_HANDLER(TBVN_PAGEACTIVATED, OnTabPageActivated)
		MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		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()

tabbrowser135.gif 最後にタブが切り替わったときと、ビューウインドウからスクリプトエラーのメッセージが送られてきたときにステータスバーにアイコンが表示されるようにする。
	//タブが選択されたときの処理
	LRESULT OnTabPageActivated(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
	{
		if(pnmh == NULL)
			return	0;

		//全てのビューに対してタブ変更があったことを通知
		{
			int		i;
			int		nCount;
			CTabBrowser100View*	pView;

			int kk=m_view.GetActivePage();

			nCount = m_view.GetPageCount();
			for(i = 0; i < nCount; i++)
			{
				pView = GetPageView(i);
				if(pView == NULL)
					continue;

				if(pnmh->idFrom == i)
					pView->OnTabPageChange(true);
				else
					pView->OnTabPageChange(false);
			}
		}

		bool		ret;
		CTabBrowser100View*	pView;

		pView = GetActivePageView();		//アクティブビュー取得
		if(pView == NULL)
			return	0;

		//アドレスバーのURL変更
		{
			CAtlString	strURL;

			ret = pView->GetURL(strURL);		//URL取得
			if(ret)
				_wndAddressBar.SetWindowText(strURL);
		}

		//ステータスバーのテキスト変更
		{
			CAtlString	strText;

			pView->GetLastStatusText(strText);
			if(::IsWindow(m_hWndStatusBar))
				::SetWindowText(m_hWndStatusBar,strText);
		}

		//■追加
		//ステータスバーのエラーアイコン変更
		{
			CStatusBarCtrl	wndStatusBar = m_hWndStatusBar;

			if(wndStatusBar.IsWindow())
			{
				if(pView->IsPageError())
					wndStatusBar.SetIcon(0,_cIconList.GetIcon(CIconManager::ICON_WARNING_SM));
				else
					wndStatusBar.SetIcon(0,NULL);
			}
		}

		//プログレス変更
		{
			long	nProgress;
			long	nProgressMax;

			pView->GetLastProgress(nProgress,nProgressMax);
			RefreshProgressBar(nProgress,nProgressMax);
		}

		return	0;
	}


	//■追加
	//ステータスバーのエラーアイコン変更
	LRESULT OnDnpScriptError(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		BOOL	bPageError = (BOOL)wParam;
		CStatusBarCtrl	wndStatusBar = m_hWndStatusBar;

		if(wndStatusBar.IsWindow())
		{
			if(bPageError)
				wndStatusBar.SetIcon(0,_cIconList.GetIcon(CIconManager::ICON_WARNING_SM));
			else
				wndStatusBar.SetIcon(0,NULL);
		}

		return	0;
	}

tabbrowser136.gif
これでビルド/実行するとページにエラーがあるときだけステータスバーにアイコンが表示されるようになった。

だんだんビューからメインウインドウへの通知が増えてきてそろそろソースコードが崩壊しそうな雰囲気があるため整理したいところだがまだしばらく誤魔化しながら実装し続けることにする。

次回はページにエラーがあるときにステータスバーをダブルクリックすることでエラーの詳細情報が表示されるようにする。

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


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