『ながっちゃん』のページ

気まぐれ兄ちゃんの独り言

#5[CPP]ダイアログ上のコントロールの背景色を変える

内容

ダイアログ上のコントロールの背景色を任意の色に変更する方法です。

解説

 ダイアログボックス上のコントロールのf背景色を変更するには、メッセージハンドラOnCtlColor( )で色を設定します。
 サンプルは、2つのスタティックテキストと2つのエディットボックスとリストボックスとピクチャコントロールを持つダイアログボックスを作成しています。
 まず、ダイアログボックスの背景と各コントロールの背景を塗りつぶす色とブラシはメンバー変数とし、メッセージハンドラOnInitDialog( )で定義します。
 次に、OnCtlColor( )において各コントロールの背景色を設定します。基本的には背景として塗りつぶしたい色を持つブラシ ハンドルをOnCtlColor( )の戻り値として渡します。また、スタティックテキスト、リストボックス、それから、Read Onlyのエディットボックスは、CTLCOLOR_STATICメッセージにおいてバックグラウンド モードを透明にします(pDC->SetBkMode(TRANSPARENT))。バックグラウンド モードを透明にしないと文字の部分の背景色が設定されているの色になります。その例が以下のサンプルのスタティックテキスト2で、コントロールの背景色は黄色ですが文字の部分のみ背景色を赤にしています。

Read Onlyでない通常のエディットボックスはちょっと特殊で、CTLCOLOR_EDITCTLCOLOR_MSGBOX メッセージの両方で塗りつぶしたい色を持つブラシ ハンドルをOnCtlColor( )の戻り値として渡し、更に、CTLCOLOR_EDITメッセージでpDC->SetBkColor(  )を呼び出して色を設定します。
 なお、ダイアログボックス自体の背景色を変える方法は#4[CPP]ダイアログの背景色を変えるをご覧ください。

サンプル

< ダイアログボックスの例>
コントロールを配置したダイアログサンプル

// CdialogsmapleDlg ダイアログ
class CdialogsmapleDlg : public CDialog
{
// コンストラクション
public:
	CdialogsmapleDlg(CWnd* pParent = NULL);	// 標準コンストラクタ

// ダイアログ データ
	enum { IDD = IDD_DIALOGSMAPLE_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV サポート


// 実装
protected:
	HICON m_hIcon;

	// 生成された、メッセージ割り当て関数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
private:
	COLORREF m_backColor;
	CBrush m_backBrush;
	COLORREF m_Brush1Color;
	CBrush m_Brush1;
	COLORREF m_Brush2Color;
	CBrush m_Brush2;
	COLORREF m_Brush3Color;
	CBrush m_Brush3;
};

BOOL CdialogsmapleDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// "バージョン情報..." メニューをシステム メニューに追加します。

	// IDM_ABOUTBOX は、システム コマンドの範囲内になければなりません。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
	//  Framework は、この設定を自動的に行います。
	SetIcon(m_hIcon, TRUE);			// 大きいアイコンの設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンの設定

	// TODO: 初期化をここに追加します。
	// 色とブラシの定義
	m_backColor = RGB( 128, 128, 255 );				// ダイアログの背景色
	m_backBrush.CreateSolidBrush( m_backColor );	// 背景塗りつぶしのブラシ
	m_Brush1Color = RGB( 255, 255, 0 );
	m_Brush1.CreateSolidBrush( m_Brush1Color );
	m_Brush2Color = RGB( 128, 255, 0 );
	m_Brush2.CreateSolidBrush( m_Brush2Color );
	m_Brush3Color = RGB( 0, 255, 255 );
	m_Brush3.CreateSolidBrush( m_Brush3Color );
	// コントロールの初期値
	GetDlgItem( IDC_EDIT1 )->SetWindowText( "エディットボックス1" );
	GetDlgItem( IDC_EDIT2 )->SetWindowText( "Read Only エディットボックス2" );
	CListBox* pList1 = (CListBox*)GetDlgItem( IDC_LIST1 );
	pList1->AddString( "ListBox item1" );
	pList1->AddString( "ListBox item2" );
	

	return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

BOOL CdialogsmapleDlg::OnEraseBkgnd(CDC* pDC)
{
	// TODO : ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。
	// 古いブラシを保存する。
	CBrush* pOldBrush = pDC->SelectObject(&m_backBrush);

	// 再描画対象領域の背景の塗りつぶし
	CRect rect;
	pDC->GetClipBox(&rect); 
	pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);

	pDC->SelectObject(pOldBrush);
	return TRUE;

	//return CDialog::OnEraseBkgnd(pDC);
}

HBRUSH CdialogsmapleDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO :  ここで DC の属性を変更してください。
	CBrush* pOldBrush;
	CRect rect;
	switch ( nCtlColor )
	{
	case CTLCOLOR_STATIC:	// 全てのスタティックコントロール
		switch (pWnd->GetDlgCtrlID() )
		{
		case IDC_STATIC1: // スタティックテキスト1
			pDC->SetBkMode(TRANSPARENT);
			return (HBRUSH)m_backBrush;
			break;
		case IDC_STATIC2: // スタティックテキスト2
			pDC->SetBkColor( RGB( 255, 0, 0 ) );	// 文字の部分の背景色設定
			return (HBRUSH)m_Brush1;
			break;
		case IDC_EDIT2: // Read Only エディットボックス2
			pDC->SetBkMode(TRANSPARENT);
			return (HBRUSH)m_Brush2;
			break;
		case IDC_STATIC4:					// Picture Control(フレーム)
			pOldBrush = (CBrush*)pDC->SelectObject( &m_Brush1 );
			pDC->GetClipBox(&rect);
			pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);     // 対象領域を消去。
			pDC->SelectObject(pOldBrush);
			break;
		}
		break;
	case CTLCOLOR_EDIT: // エディットボックス1
		pDC->SetBkColor( m_Brush3Color );
	case CTLCOLOR_MSGBOX: // エディットボックス1
		return (HBRUSH)m_Brush3;
		break;
	case CTLCOLOR_LISTBOX: // ListBox
		pDC->SetBkMode(TRANSPARENT);
		return (HBRUSH)m_Brush2;
		break;
	default:
		return (HBRUSH)m_backBrush;
		break;
	}

	// TODO :  既定値を使用したくない場合は別のブラシを返します。
	return hbr;
}

<実行結果>
 背景色を変更したダイアログ上のコントロール