第42回 ステータスバーにペインを用意する (タブブラウザーを作る)

tabbrowser171.gif
前回まで少し機能拡張を休んでソースコードの整理を行っていた。今回はCIELikeStatusbarクラスを修正してステータスバーのペインを増やす。

ステータスバーでは複数のペインを扱うと、どのペインがどのインデックスなのかごちゃごちゃして分かりにくくなることがある。それを防ぐため今回はenumでペインを定義してしまう。
	//■処理変更
	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		bHandled = FALSE;

		UpdateLayout();

		return	0;
	}


	//■追加
	//ステータスバーペインのインデックス
	enum	ENUM_PAIN
	{
		PAIN_DEFAULT = 0,			//メッセージ表示やアイコン表示
		PAIN_PROGRESS,				//プログレスバー表示
		PAIN_RESERVED,				//
		PAIN_POPUP,					//ポップアップブロック有効/無効
		PAIN_ADDON,					//アドオンの管理
		PAIN_PRIVACY_REPORT,		//クッキーアイコンやプライバシーレポート表示
		PAIN_SECURITY_REPORT,		//SSLアイコンやセキュリティレポート表示
		PAIN_SECURITY,				//SmartFilterなどの設定
		PAIN_ZONE,					//現在のゾーン表示
		PAIN_BLOCKED,				//ブロックされた項目の表示
		PAIN_ZOOM,					//ズーム設定


		PAIN_LAST					//インデックス数を示す。必ずenumの最後に配置すること
	};

tabbrowser172.gif 指定されたペインの横幅を返す関数を用意する。ペインのスペルがPAINになったりPANEになったり統一感がないが、細かいことは気にせずそのうち修正することにして今回は保留しておく。
	//■追加
	//ペインの「幅」を返す
	int	GetPaneWidth(UINT nIndex)
	{
		if(nIndex >= PAIN_LAST)
			return	0;

		switch(nIndex)
		{
		case	PAIN_DEFAULT:
			{
				int		i;
				int		nWidth;
				CRect	rect;

				//PAIN_DEFAULT以外の部分の幅を計算
				nWidth = 0;
				for(i = 1; i < PAIN_LAST; i++)
					nWidth += GetPaneWidth(i);

				//ステータスバー幅から合計幅を引いた値がPAIN_DEFAULTの幅
				GetClientRect(&rect);
				nWidth = rect.Width() - nWidth;

				if(nWidth >= 0)
					return	nWidth;

				return	0;			//マイナスになるならゼロを返す
			}
			break;

		case	PAIN_PROGRESS:
			if(_nLastProgressMax < _nLastProgress)
				return	0;
			return	100;

		case	PAIN_RESERVED:
		case	PAIN_POPUP:
		case	PAIN_ADDON:
		case	PAIN_PRIVACY_REPORT:
		case	PAIN_SECURITY_REPORT:
		case	PAIN_SECURITY:
			return	20;

		case	PAIN_ZONE:
			return	100;

		case	PAIN_BLOCKED:
			return	30;

		case	PAIN_ZOOM:
			return	60;
		}

		ATLASSERT(0);
		return	0;
	}

tabbrowser173.gif ステータスバーのレイアウトを設定する関数。ステータスバーのレイアウトはSetParts(SB_SETPARTS)で設定できるが、この関数の引数に渡す整数配列は、ペインの「幅」ではなく、右側の「座標」になることに注意。GetPaneWidthの引数をそのまま渡すことはできない。
	//■追加
	//ステータスバーレイアウト設定
	bool	UpdateLayout(void)
	{
		if(IsWindow() == FALSE)
			return	false;				//ステータスバー表示してない

		//ステータスバーのペイン作成
		//本当は現在のペイン数などを見て更新した方がいいのだろうけど、面倒だからそのまま設定
		{
			int		i;
			int		pnParts[PAIN_LAST];
			int		nOffset;
			CStatusBarCtrl	wndStatusBar = m_hWnd;

			nOffset = 0;
			for(i = 0; i < PAIN_LAST; i++)
			{
				pnParts[i] = GetPaneWidth(i) + nOffset;
				nOffset = pnParts[i];						//pnPartsは「幅」ではなく座標を入れる必要があるので、幅から座標に変換するためnOffsetを利用
			}

			//ペイン作成
			wndStatusBar.SetParts(PAIN_LAST,pnParts);
		}

		RefreshProgressBar();		//プログレスバー表示更新

		return	true;
	}

tabbrowser174.gif これまではプログレスバーの進行状況設定時にステータスバーのペインを設定していた。これからはUpdateLayoutがその役を担うことになるので、ペイン作成関連処理を削除し、またきちんとUpdateLayoutが呼ばれるようにしておく。
	//bVisible=falseならプログレスバーを消す
	//nProgress < 0、nProgressMax < 0ならプログレス設定はしない
	//nProgressMax < nProgressなら強制的に非表示にする
	bool	RefreshProgressBar(int nProgress=-1,int nProgressMax=-1,bool bVisible=true)
	{
		if((nProgress >= 0 && nProgressMax  >= 0) || (nProgressMax < nProgress))
		{
			//状態を保存しておく
			_nLastProgress		= nProgress;
			_nLastProgressMax	= nProgressMax;
		}

		if(::IsWindow(m_hWnd) == FALSE)
			return	false;				//ステータスバー表示してない

		//■削除
		//int		nProgressWidth = 100;			//■プログレスバーの幅は100px固定とする
		CRect	rect;
		CStatusBarCtrl	wndStatusBar = m_hWnd;

		if(_nLastProgressMax < _nLastProgress)
			bVisible = false;


		//■追加
		if(bVisible == false)
		{
			int		nRet;
			int		pnParts[PAIN_LAST];

			nRet = wndStatusBar.GetParts(PAIN_LAST,pnParts);

			if(nRet > PAIN_PROGRESS)
			{
				if(pnParts[PAIN_PROGRESS] != pnParts[PAIN_PROGRESS - 1])
					UpdateLayout();
			}
		}


		//■削除
		//if(bVisible == false)
		//	nProgressWidth = 0;

		//■削除
		////ステータスバーのペインの作成/更新
		//{
		//	int		pnParts[2];						//2つペインを作成(1つはデフォルト、もう1つはプログレスバー用)

		//	wndStatusBar.GetClientRect(&rect);
		//	pnParts[0] = rect.Width() - nProgressWidth;
		//	pnParts[1] = rect.Width();

		//	wndStatusBar.SetParts(sizeof(pnParts) / sizeof(pnParts[0]),pnParts);
		//}


		//プログレスバーの生成/更新
		{
			wndStatusBar.GetRect(1,&rect);			//2つめのペインをプログレスバーに利用する

			if(_wndProgressBar.IsWindow() == FALSE)
				_wndProgressBar.Create(m_hWnd,rect,0,WS_CHILD);	//プログレスバーを生成
			else
				_wndProgressBar.MoveWindow(&rect);			//位置を移動

			if(bVisible)
			{
				if(_wndProgressBar.IsWindowVisible() == FALSE)
					_wndProgressBar.ShowWindow(SW_NORMAL);		//可視に
			}
			else
			{
				if(_wndProgressBar.IsWindowVisible())
					_wndProgressBar.ShowWindow(SW_HIDE);		//不可視に
			}

			//プログレスの設定
			if(_nLastProgress >= 0)
				_wndProgressBar.SetRange(0,_nLastProgressMax);
			if(_nLastProgress >= 0)
				_wndProgressBar.SetPos(_nLastProgress);
		}

		return	true;
	}

tabbrowser175.gif 外部から呼ばれるステータスバー更新用関数内でもUpdateLayoutが呼ばれるようにしておく。UpdateLayout内ではプログレスバーの設定もしているのでRefresh内のプログレスバー更新処理は削除した。
	//ステータスバー表示更新
	bool	Refresh(bool bCapture)
	{
		if(bCapture == false)
		{
			if(_wndProgressBar.IsWindow())
			{
				if(_wndProgressBar.IsWindowVisible())
					_wndProgressBar.ShowWindow(SW_HIDE);		//不可視に
			}
			return	true;
		}

		if(IsWindow() == FALSE)
			return	false;

		//■追加
		UpdateLayout();		//レイアウト調整

		//ステータスバーのテキスト変更
		{
			SetText(_strText);
		}

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

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

		//■削除
		////プログレス変更
		//{
		//	RefreshProgressBar(_nLastProgress,_nLastProgressMax);
		//}

		return	true;
	}

tabbrowser176.gif
これでビルド/実行するとステータスバーにペインが増えた。

次回はステータスバーがダブルクリックされたときにプライバシーレポートの表示をする。

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


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