|
コンボボックスの色変更
今回はコンボボックスの色の変更方法をやります。さっそく、前回のプロジェクトに次のように1つボタンを追加します。

"色選択"ボタンが押されると、色選択ダイアログを表示し、コンボボックスの文字列を、指定した色で描画します。
色情報はCOLORREF型の変数で扱います。ここではダイアログのメンバ変数に保持します。

では、コードを実装していきましょう。まずは、コンストラクタで色情報の初期値を入れておきます。
CComboDlg::CComboDlg(CWnd* pParent /*=NULL*/)
: CDialog(CComboDlg::IDD, pParent)
, m_xvCombo(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_color = RGB(255, 0, 0);
}
|
コントロールが描画されるときは、親ウィンドウにWM_CTLCOLORメッセージが送られます。このメッセージが送られたときに、コンボボックスの色を変更します。
コンボボックスは、エディットボックスとリストボックスの組み合わせでできています。コンボボックス自体の色変更をするのではなく、これらの部品に色変更処理を追加します。
ダイアログクラスのプロパティからメッセージアイコンをクリックし、WM_CTLCOLORを選択し、CWnd::OnCtlColor()関数をオーバーライドします。

OnCtlColor()関数では、次のようにコンボボックスの色変更処理を追加します。
HBRUSH CComboDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
HWND hwnd = NULL;
COMBOBOXINFO comboInfo;
bool bChangeColor = false;
int err = 0;
hwnd = pWnd->GetSafeHwnd();
comboInfo.cbSize = sizeof COMBOBOXINFO;
if (!m_xcCombo.GetComboBoxInfo(&comboInfo)) err = 1;
// コンボボックスの色変更
if (!err)
{
// エディット
if (nCtlColor == CTLCOLOR_EDIT)
{
// 標準、ドロップダウンはhwndItem
// ドロップダウンリストはhwndCombo
if (hwnd == comboInfo.hwndItem ||
hwnd == comboInfo.hwndCombo)
{
bChangeColor = true;
}
}
// リスト
if (nCtlColor == CTLCOLOR_LISTBOX)
{
if (hwnd == comboInfo.hwndList) bChangeColor = true;
}
// 色変更
if (bChangeColor)
{
// 文字色
pDC->SetTextColor(m_color);
// 背景色
hbr = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
pDC->SetBkColor(RGB(0, 0, 0));
}
}
return hbr;
}
|
OnCtlColor()関数の第2引数は、描画されようとしているコントロールのポインタ、第3引数はコントロールの種類が渡されます。コンボボックスの場合は、エディットボックス、リストボックスがコンボボックスの子ウィンドウになっているので、まずそれらのウィンドウハンドルを取得しておきます。
ウィンドウハンドルを取得するには、CComboBox::GetComboBoxInfo()関数を使います。この関数を使う場合は、関数を呼ぶ前にcbSizeメンバに構造体のサイズをセットしておきます。
| BOOL CComboBox::GetComboBoxInfo(PCOMBOBOXINFO pcbi) const; |
| 説明: |
CComboBoxオブジェクトの情報を取得 |
| 引数: |
pcbi:PCOMBOBOXINFO構造体のポインタ |
| 戻り値: |
正常終了した場合はTRUE。それ以外の場合はFALSE |
OnCtlColor()の引数で渡されたウィンドウが、コンボボックスが持つエディットボックス、リストボックスのウィンドウと一致するかを調べ、一致する場合に色変更をします。
エディットボックス部分は、コンボボックスのスタイルが"標準"、"ドロップダウン"の場合はhwndItemメンバ、"ドロップダウンリスト"の場合はhwndComboメンバと比較します。
文字色の変更は、CDC::SetTextColor()関数を使います。
背景色の変更は、hbrに設定したい色のブラシをセットし、さらにCDC::SetBkColor()関数を実行します。ここではストックオブジェクトを使っていますが、独自の色を設定したい場合は、独自のブラシを作成します。
もしhbrにブラシをセットしないと、次のようになってしまいます。文字領域以外の背景部分が白いままになってしまいます。

次は"色選択"ボタンが押されたときのイベントハンドラです。
// "色選択"ボタン押下
void CComboDlg::OnBnClickedColorsel()
{
CColorDialog CColorDialog(m_color);
int err = 0;
// 色選択ダイアログ表示
if (CColorDialog.DoModal() == IDOK)
{
// 選択された色を取得
m_color = CColorDialog.GetColor();
// 表示更新
Invalidate();
}
return;
}
|
色選択のダイアログは、CColorDialogクラスを使います。コンストラクタにCOLORREF型の変数を渡すと、初期状態でその色が選択された状態になります。
選択された色を取得するには、CColorDialog::GetColor()関数を使います。選択された色でコンボボックスを更新するために、CWnd::Invalidate()関数を1度呼び出します。こうするとWM_CTLCOLORメッセージが発行されます。
では、ビルドして実行してみましょう。色選択ダイアログで任意の色を選択すると、コンボボックスの文字色が変わります。



|