S-JIS[1998-02-11/2004-03-10]

CViewの背景色の変え方

AppWizardで作成したSDIのMFCアプリケーションで CView(の派生クラス)の背景色を変える方法です。
[1999-04-12]以前から紹介していたやり方と 基本的には同じですが、実行上の無駄が少なくなっていると思います。


背景色を変えるには、OnDraw()の前に呼ばれるOnEraseBkgnd()を利用します。 OnEraseBkgnd()が背景を消去する処理を行っているので、ここに背景色を渡せばいい訳です。


コーディングは、以下のような手順になります。

  1. OnInitialUpdate()をオーバーライドし、 WM_ERASEBKGNDWM_DESTROYのメッセージのハンドラを作成します。
  2. 背景色を保持する為のブラシと、過去の背景色を保存しておく為のブラシを用意します。
  3. ウィンドウ作成時に背景色のブラシを作成するため、OnInitialUpdate()をコーディングします。
  4. 毎回の描画前にテキスト用の背景色を変更するため、OnEraseBkgnd()をコーディングします。
  5. ウィンドウ破棄時に背景色のブラシを削除するため、OnDestroy()をコーディングします。

OnEraseBkgnd()はテキスト用の背景色、つまりpDC->TextOut()で文字を表示する時の背景色の変更の為に呼んでいるので、 テキストを出力しないなら上記のOnEraseBkgnd()関連の部分は不要です。


backView.h:
class CBackView : public CView
{
〜
// オーバーライド
	// ClassWizard は仮想関数を生成しオーバーライドします。
	//{{AFX_VIRTUAL(CBackView)
	public:
	virtual void OnDraw(CDC* pDC);  // このビューを描画する際にオーバーライドされます。
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	virtual void OnInitialUpdate();
〜
	//}}AFX_VIRTUAL
〜
// 生成されたメッセージ マップ関数
protected:
	//{{AFX_MSG(CBackView)
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnDestroy();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

private:
	CBrush m_BkgndBrush;	//背景色を保持するブラシ
	HBRUSH m_hOldBkgndBrush;	//以前の背景色のバックアップ
};

backView.cpp:
BEGIN_MESSAGE_MAP(CBackView, CView)
	//{{AFX_MSG_MAP(CBackView)
	ON_WM_ERASEBKGND()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
〜
END_MESSAGE_MAP()
〜
CBackView::CBackView()
{
	m_hOldBkgndBrush=0;	//ブラシハンドラの初期化
}

//OnInitialUpdate()をオーバーライド
void CBackView::OnInitialUpdate() 
{
	CView::OnInitialUpdate();

	// TODO: この位置に固有の処理を追加するか、または基本クラスを呼び出してください
	//背景色ブラシの作成と登録
	if(m_BkgndBrush.m_hObject==0){
		m_BkgndBrush.CreateSolidBrush(RGB(0,128,0));	//背景色
		m_hOldBkgndBrush=(HBRUSH)SetClassLong(
			GetSafeHwnd(),
			GCL_HBRBACKGROUND,
			(LONG)(HBRUSH)m_BkgndBrush.m_hObject
		);
	}
}

//WM_ERASEBKGNDメッセージのイベントハンドラを追加
BOOL CBackView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください

//	return CView::OnEraseBkgnd(pDC);
	BOOL ret=CView::OnEraseBkgnd(pDC);	//派生元の関数を呼ぶ

	pDC->SetBkColor(RGB(0,128,0));	//これが無いとTextOut()の背景が変わらない

	return ret;
}

//WM_DESTROYメッセージのイベントハンドラを追加
void CBackView::OnDestroy()
{
	//ブラシを元に戻す
	if(m_hOldBkgndBrush){
		SetClassLong(GetSafeHwnd(),GCL_HBRBACKGROUND,(LONG)m_hOldBkgndBrush);
		m_hOldBkgndBrush=0;
		m_BkgndBrush.DeleteObject();
	}

	CView::OnDestroy();

	// TODO: この位置にメッセージ ハンドラ用のコードを追加してください

}

VC++ページへ戻る / 技術メモへ戻る
メールの送信先:ひしだま