プロパティシートで選択されたタブの色を変更する

プロパティシートのタブをカスタマイズするには、通常はオーナードローを行う。 しかし、タブの色を変更するだけのためにオーナードローをするのは非常に手間がかかるので、 ここではオーナードローを行わずにタブの色を変更する方法を記述する。
  1. CPropertySheetの派生クラス(ここではCMySheetとする)を用意し、このクラスでプロパティシートを作成する。
  2. CTabCtrlの派生クラス(ここではCMyTabCtrlとする)を用意し、そのインスタンスをCMySheetのメンバとする。
  3. CMySheet::OnInitDialog関数をオーバーライドし、この中でCMySheet::GetTabControl()を呼び出してタブコントロールを取得、 CWnd::SubclassWindow()を使ってCMyTabCtrlのインスタンスをサブクラス化する。
  4. CMyTabCtrl::OnPaint関数をオーバーライドして描画処理を行う。

	// CMySheetのヘッダへの記述
	#include "MyTabCtrl.h"    // CMyTabCtrlのヘッダをインクルードする

	class CMySheet : public CPropertySheet
	{
		……
	private:
		CMyTabCtrl m_Tab;
	};

	// CMySheetのOnInitDialog関数の実装
	BOOL CMySheet::OnInitDialog() 
	{
		BOOL bResult = CPropertySheet::OnInitDialog();
	
		// TODO: この位置に固有のコードを追加してください
		CTabCtrl* pTab = GetTabControl();
	
		if( m_Tab.GetSafeHwnd() == NULL ) {
			m_Tab.SubclassWindow(pTab->GetSafeHwnd());
		}

		return bResult;
	}

	// CMyTabCtrlのヘッダへの記述
	class CMyTabCtrl : public CTabCtrl
	{
		……
	private:
		CFont m_Font;
	};

	// CMyTabCtrlのOnPaint関数の実装
	void CMyTabCtrl::OnPaint() 
	{
		// 最初にデフォルトの描画処理を行うため、以下の処理を記述する
		Default();
			//または以下の記述
			//const MSG *msg = GetCurrentMessage();
			//DefWindowProc( msg->message, msg->wParam, msg->lParam );

		// デバイスコンテキストはCClientDCを使用する
		//CPaintDC dc(this); // 描画用のデバイス コンテキスト
		CClientDC dc(this);

		// TODO: この位置にメッセージ ハンドラ用のコードを追加してください
		CRect rect;
		GetItemRect(GetCurSel(), &rect);  // 選択されているページのタブに外接する四角形の取得

		// タブの背景をウィンドウの色で描画(レイアウト上、四角形は少し小さくする)
		rect.InflateRect(-2, -2);
		dc.FillSolidRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
			GetSysColor(COLOR_WINDOW));

		// タブに描画する文字のフォントを設定
		// (親ウィンドウであるプロパティシートと同じフォントにする)
		// m_Fontはコントロールクラスのメンバ変数(CFont型)
		LOGFONT lf, parentlf;
		GetFont()->GetLogFont(&lf);
		GetParent()->GetFont()->GetLogFont(&parentlf);
		lf.lfHeight = parentlf.lfHeight;
		strcpy(lf.lfFaceName, parentlf.lfFaceName);
		m_Font.CreateFontIndirect(&parentlf);
		CFont* pOldFont = dc.SelectObject(&m_Font);

		// 文字を描画する
		CString str;
		CPropertyPage* pPage = ((CPropertySheet*)GetParent())->GetPage(GetCurSel());
		if( pPage->GetSafeHwnd() ) {
			pPage->GetWindowText(str);  // 現在開いているページのタブの文字を取得する
			dc.DrawText(str, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		}

		// フォントを元に戻す
		dc.SelectObject(pOldFont);
		m_Font.DeleteObject();

		// 描画用メッセージとして CTabCtrl::OnPaint() を呼び出してはいけません
	}
	

目次へ