AppWizardで作成したSDIのMFCアプリケーションで
CView(の派生クラス)の背景色を変える方法です。
[1999-04-12]以前から紹介していたやり方と
基本的には同じですが、実行上の無駄が少なくなっていると思います。
背景色を変えるには、OnDraw()の前に呼ばれるOnEraseBkgnd()を利用します。 OnEraseBkgnd()が背景を消去する処理を行っているので、ここに背景色を渡せばいい訳です。
コーディングは、以下のような手順になります。
OnEraseBkgnd()はテキスト用の背景色、つまりpDC->TextOut()で文字を表示する時の背景色の変更の為に呼んでいるので、 テキストを出力しないなら上記のOnEraseBkgnd()関連の部分は不要です。
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; //以前の背景色のバックアップ };
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: この位置にメッセージ ハンドラ用のコードを追加してください }