コンボボックスに色を付ける – プログラミング – Home

コンボボックスに色を付ける
 
通知
すべてクリア

コンボボックスに色を付ける


YASUDA
 YASUDA
(@YASUDA)
ゲスト
結合: 16年前
投稿: 24
Topic starter  

VC++2005 MFC ダイアログベース

ダイアログBOXにドロップダウン コンボボックスが2個あり、
そのそれぞれに違った色を付けたいと思っています。
IDC_COMBO1 → 赤
IDC_COMBO1 → 緑

-------------------------------------------------------------------------------
-
ComboBox を基本クラスとする
CColorComboBox クラスを新規作成して

WM_CTLCOLOR をオーバーライドして色を付ける事はできたのですが、
それぞれのコンボボックスに違った色を指定する方法がわかりません。
どうしたら良いでしょうか?

------------------------------------------------------------------------------
// CMainDlg.h メインダイアログのヘッダファイル
#include CColorComboBox.h
class CMainDlg : public CDialog
{
CColorComboBox m_combo1;
CColorComboBox m_combo2;
}

// CMainDlg.cpp メインダイアログ
void CMainDlg::DoDataExchange( CDataExchange* pDX )
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO1,m_combo1);
DDX_Control(pDX, IDC_COMBO2,m_combo2);
}

// CColorComboBox.cpp コンボボックスを基本クラスするクラス
#include CColorComboBox.h
HBRUSH CColorComboBox::OnCtrColor( CDC* pDC,CWnd* pWnd, UINT nCtlColor )
{
HBRUSH hBr = CCOmbobox::OnCtlColor(pDC,pWnd,nCtlColor);
pDC->SetBkColor( RGB( 255, 0, 0) ); //赤
hBr = m_RedBrush; //m_RedBrush.CleateSolidBrush(RGB( 255, 0, 0));
}


引用解決済
トピックタグ
YASUDA
 YASUDA
(@YASUDA)
ゲスト
結合: 16年前
投稿: 24
Topic starter  

間違えて連投してしまいました。


返信引用
とおりすがり
 とおりすがり
(@とおりすがり)
ゲスト
結合: 23年前
投稿: 180
 

CColorComboBox に文字の色と背景色と、背景色用のブラシを設定する関数と
設定を持てば良いのでは


返信引用
YASUDA
 YASUDA
(@YASUDA)
ゲスト
結合: 16年前
投稿: 24
Topic starter  

とおりすがりさんコメントありがとうございます。

2つのコンボボックスの色をそれぞれ違う色に設定しようとしているのですが、
方法がわかりません。

pWnd->GetDlgCtrID()が全部 「1001」 で、
コンボボックスコンボボックスを識別できません。

#include CColorComboBox.h
HBRUSH CColorComboBox::OnCtrColor( CDC* pDC,CWnd* pWnd, UINT nCtlColor )
{
HBRUSH hBr = CCOmbobox::OnCtlColor(pDC,pWnd,nCtlColor);

if(pWnd->GetDlgCtrID() == IDC_COMBO1){
pDC->SetTextColor( RGB( 0, 0, 0) ); //黒文字
pDC->SetBkColor( RGB( 255, 0, 0) ); //赤
hBr = m_RedBrush; //m_RedBrush.CleateSolidBrush(RGB( 255, 0, 0));
}
else if(pWnd->GetDlgCtrID() == IDC_COMBO2){
pDC->SetTextColor( RGB( 0, 0, 0) ); //黒文字
pDC->SetBkColor( RGB( 0, 255, 0) ); //赤
hBr = m_GreenBrush; //m_GreenBrush.CleateSolidBrush(RGB( 0, 255, 0));
}
return hBr;
}


返信引用
YASUDA
 YASUDA
(@YASUDA)
ゲスト
結合: 16年前
投稿: 24
Topic starter  

>aetos 2009/07/23(木) 11:04:58

>OnCtlColor の nCtlColor がコントロール ID なので、これでどのコントロールの
>OnCtlColor が呼ばれているのかを識別して処理を分けます。

>…ん? OnCtlColor を CComboBox の派生クラスに実装してるの?
>CMainDlg で処理するなら上記のようになります。
ヘルプを読んだらドロップダウンコンボボックスのリストボックスでは、
OnCtlColorは呼び出されません。
と書いてあったので、オーバーライドしてみました。

>今の形で行くなら、CColorComboBox に「自分の色」を何らかの形で伝えてやればよい
>の
>では。メンバ関数増やすとか。
試行錯誤中ですが、まだうまくいっていません。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> ヘルプを読んだらドロップダウンコンボボックスのリストボックスでは、
> OnCtlColorは呼び出されません。
> と書いてあったので、オーバーライドしてみました

はい。
俺嘘言いました。ごめんなさい。

しかも、nCtlColor はコントロールの ID じゃなくてコントロールのタイプでした。

で、自分でやってみました。
うまくいったので手順を書いておきます。

1:CComboBox から派生した CColorComboBox クラスを作ります。
2:CColorComboBox にメンバ変数 HBRUSH m_hBrush を追加します。
3:CColorComboBox で OnCtlColor をオーバーライドし、nCtlColor が
  CTLCOLOR_LISTBOX のときに pDC->SetBkMode( TRANSPARENT ) してから
  m_hBrush を返すように書きます。
4:リソースエディタでダイアログ上に配置したコンボボックスを選択して
  「変数の追加」をし、CColorComboBox 型のメンバ変数を追加します。
5:ダイアログの OnInitDialog で、CColorComboBox の m_hBrush に
  任意の色のブラシを設定します。

コードも載せちゃいますね。

== CColorComboBox.h ==

#pragma once

// CColorComboBox

class CColorComboBox : public CComboBox
{
DECLARE_DYNAMIC(CColorComboBox)

public:
CColorComboBox();
virtual ~CColorComboBox();

protected:
DECLARE_MESSAGE_MAP()

public:
HBRUSH GetBrush(void) const
{
return m_hBrush;
}

void SetBrush(HBRUSH hBrush)
{
DeleteObject( m_hBrush );
m_hBrush = hBrush;
}

private:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
HBRUSH m_hBrush;
};

== CColorComboBox.cpp ==

// ColorComboBox.cpp : 実装ファイル
//

#include stdafx.h
#include ColorCombo.h
#include ColorComboBox.h

// CColorComboBox

IMPLEMENT_DYNAMIC(CColorComboBox, CComboBox)

CColorComboBox::CColorComboBox()
: m_hBrush( static_cast< HBRUSH >( GetSysColorBrush(
COLOR_WINDOW ) ) )
{
}

CColorComboBox::~CColorComboBox()
{
}

BEGIN_MESSAGE_MAP(CColorComboBox, CComboBox)
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()

// CColorComboBox メッセージ ハンドラ

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

// TODO: ここで DC の属性を変更してください。
// TODO: 既定値を使用したくない場合は別のブラシを返します。
if( nCtlColor == CTLCOLOR_LISTBOX )
{
pDC->SetBkMode( TRANSPARENT );
return m_hBrush;
}

return hbr;
}

== CColorComboDlg.cpp(抜粋) ==

// CColorComboDlg メッセージ ハンドラ

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

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

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

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
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_combo1.SetBrush( CreateSolidBrush( RGB( 255, 0, 0 ) ) );
m_combo2.SetBrush( CreateSolidBrush( RGB( 0, 255, 0 ) ) );

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


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

改良しました。

== CColorComboBox.h ==

#pragma once

// CColorComboBox

class CColorComboBox : public CComboBox
{
DECLARE_DYNAMIC(CColorComboBox)

public:
CColorComboBox();
virtual ~CColorComboBox();

protected:
DECLARE_MESSAGE_MAP()

public:
COLORREF GetBackgroundColor() const
{
return m_color;
}

void SetColor( COLORREF color )
{
DeleteObject( m_hBrush );

m_color = color;
m_hBrush = CreateSolidBrush( color );
}

private:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);

COLORREF m_color;
HBRUSH m_hBrush;
};

== ColorComboBox.cpp ==

// ColorComboBox.cpp : 実装ファイル
//

#include stdafx.h
#include ColorCombo.h
#include ColorComboBox.h

// CColorComboBox

IMPLEMENT_DYNAMIC(CColorComboBox, CComboBox)

CColorComboBox::CColorComboBox()
:
m_color( GetSysColor( COLOR_WINDOW ) ),
m_hBrush( static_cast< HBRUSH >( GetSysColorBrush( COLOR_WINDOW ) ) )
{
}

CColorComboBox::~CColorComboBox()
{
DeleteObject( m_hBrush );
}

BEGIN_MESSAGE_MAP(CColorComboBox, CComboBox)
ON_WM_CTLCOLOR()
ON_WM_CTLCOLOR_REFLECT()
END_MESSAGE_MAP()

// CColorComboBox メッセージ ハンドラ

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

switch( nCtlColor )
{
case CTLCOLOR_EDIT:
case CTLCOLOR_LISTBOX:
pDC->SetBkMode( TRANSPARENT );
pDC->SetBkColor( m_color );

return m_hBrush;
}

return hbr;
}

HBRUSH CColorComboBox::CtlColor(CDC* pDC, UINT nCtlColor)
{
switch( nCtlColor )
{
case CTLCOLOR_EDIT:
pDC->SetBkMode( TRANSPARENT );
pDC->SetBkColor( m_color );

return m_hBrush;
}

return NULL;
}

== ColorComboDlg.cpp(抜粋) ==

// CColorComboDlg メッセージ ハンドラ

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

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

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

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
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_combo1.SetColor( RGB( 255, 0, 0 ) );
m_combo2.SetColor( RGB( 0, 255, 0 ) );

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


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

書き忘れ。

ON_WM_CTLCOLOR_REFLECT メッセージハンドラを追加するには、クラス ビューで
CColorComboBox が選択されている状態で、プロパティ ウィンドウでメッセージを選択
し、「=WM_CTLCOLOR」を選びます。
頭に = がない方だと OnCtlColor になっちゃいますので注意。


返信引用
YASUDA
 YASUDA
(@YASUDA)
ゲスト
結合: 16年前
投稿: 24
Topic starter  

aetosさん丁寧に教えて頂きありがとうございます。

載せて頂いたコードを参考にして
希望していた動作ができました。

サブクラス化がPOINTと考え、その辺を色々調べていたのですが、
色々方法があるのですね!

勉強になりました。
今後ともよろしくお願い致します。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました