今回はMFCアプリで頻繁に使うコントロールの一つ、
CComboBoxクラスの操作方法について。
またもや自分がよく使う操作の備忘録です。
準備
ここら辺はこのシリーズ(?)おなじみ。
プロジェクト作成
プロジェクトの作成方法、コントロールの配置方法は
こちらをご覧ください。
今回のプロジェクト名は「CComboBoxTest」にします。
コントロールID
今回はコンボボックスを用意します。
配置後、IDを変更します。
変更方法は、以前CStaticの操作時に書いてますのでご参考に。
今回はボタンをIDC_COMBO_TESTにします。
ビルド
一度ビルドしておきます。

コンボボックスの種類
プロパティを見ると、
ドロップダウンと、ドロップダウンリストがあります。

自分は通常、ドロップダウンリストを使います。
ドロップダウンはコンボボックス内を変更できますが、
ドロップダウンリストは変更できません。
文字挿入
今回もGetDlgItem方式で進めていきます。
プロジェクト名をCComboBoxTestで作成したので、
CComboBoxTestDlg.cppを開きます。
InsertString
OnInitDialog内に処理を記述。
BOOL CCComboBoxTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_TEST);
pCombo->InsertString(0, _T("1番目の選択肢"));
pCombo->InsertString(1, _T("2番目の選択肢"));
pCombo->InsertString(2, _T("3番目の選択肢"));
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}InsertString(番号, 文字列)で、どの位置にどの文字列を入れるかを決定します。
ビルドするとこんな感じ。

因みに、下のように作成した場合、
// TODO: 初期化をここに追加します。
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_TEST);
pCombo->InsertString(0, _T("1番目の選択肢"));
pCombo->InsertString(2, _T("2番目の選択肢"));
pCombo->InsertString(1, _T("3番目の選択肢"));2番目の選択肢は「そもそも1番目がないじゃん」って判定で
コンボボックスに設定されません。

AddString
AddStringでも追加できます。
こちらは最後に引数の文字を追加します。
BOOL CCComboBoxTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_TEST);
pCombo->InsertString(0, _T("1番目の選択肢"));
pCombo->InsertString(1, _T("2番目の選択肢"));
pCombo->InsertString(2, _T("3番目の選択肢"));
pCombo->AddString(_T("AddStringで加えた"));
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
選択肢設定
SetCurSel
どの選択肢を表示させるか設定します。
試しにOnInitDialogに記載。
BOOL CCComboBoxTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_TEST);
pCombo->InsertString(0, _T("1番目の選択肢"));
pCombo->InsertString(1, _T("2番目の選択肢"));
pCombo->InsertString(2, _T("3番目の選択肢"));
pCombo->AddString(_T("AddStringで加えた"));
pCombo->SetCurSel(1); // 上から2番目をセット
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}これで初期状態は「2番目の選択肢」が選択された状態になります。

SelectString
こちらは文字列をから選択肢を決定する方法。
今までの例だと少しわかりづらいので、挿入する文字列を変えます。
BOOL CCComboBoxTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_TEST);
pCombo->AddString(_T("Apple")); // 1番目にApple
pCombo->AddString(_T("Banana")); // 2番目にBanana
pCombo->AddString(_T("Orange")); // 3番目にOrange
pCombo->AddString(_T("Apple Pie")); // 4番目にApple Pie
pCombo->SelectString(-1, _T("Apple")); // Index0から検索スタート
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}この場合、Appleが初期状態で選択されます。

引数を0にした場合
pCombo->SelectString(0, _T("Apple")); // Index1から検索スタートBananaから検索が始まるため、
Banana⇒Orange⇒Apple Pie ←あった!
となり、Apple Pieが選択されます。

選択肢にないものが第2引数にある場合
pCombo->SelectString(-1, _T("Cherry")); // そんな文字列ない!!何も選択されない状態になります。
ボックス部 幅変更
実はこれ最近業務で知ったのですが。
こんな感じで作った場合
BOOL CCComboBoxTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_TEST);
pCombo->InsertString(0, _T("1番目の選択肢"));
pCombo->InsertString(1, _T("2番目の選択肢"));
pCombo->InsertString(2, _T("3番目の選択肢"));
pCombo->AddString(_T("AddStringで加えた"));
pCombo->AddString(_T("あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめも"));
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}コントロールの幅の大きさによっては見切れてしまいます。

勿論、幅自体を長く調整すればいいじゃん、って話もありますが。
設計上「コンボボックスの幅は広げるな」となることもあります。
じゃあどうしようか。
選択中だけ幅を広げればいいのでは??
というわけでSetDroppedWidthの出番。
BOOL CCComboBoxTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_TEST);
pCombo->InsertString(0, _T("1番目の選択肢"));
pCombo->InsertString(1, _T("2番目の選択肢"));
pCombo->InsertString(2, _T("3番目の選択肢"));
pCombo->AddString(_T("AddStringで加えた"));
pCombo->AddString(_T("あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめも"));
pCombo->SetDroppedWidth(500); // 選択中のボックス幅は500ピクセル
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}14行目にボックス幅を調整する関数を入れました。
これにより、ドロップダウンを選択すると

コンボボックス自体は以前と同じ大きさですが、
選択肢のボックス幅は広がってくれました。
注意なのが、
ボックス幅は広げることはできますが、狭めることはできません。
つまり、元のコンボボックスの幅よりも小さいピクセル数を引数に渡すと、
見た目は変更前と変わりありません。
試しに1,000ピクセルなどで試して、
徐々に小さくして最適幅を探すのがいいのかもしれませんね。
イベント処理
一度イベント処理の紹介。
自分がよく利用するのはコンボボックスが変更された後の処理ですかね。
リソース画面からコンボボックスを右クリックし、
「イベントハンドラーの追加」を選択します。

メッセージの種類はCBN_SELCHANGE、
クラスはCCCombBoxTestDlgを選択にするのを忘れずに。
(今更ながらCが多くて見づらいと感じました…)
CComboBoxTestDlg.cppに関数が追加されます。
void CCComboBoxTestDlg::OnCbnSelchangeComboTest()
{
// TODO: ここにコントロール通知ハンドラー コードを追加します。
}選択肢取得
先ほど追加した関数に、どの選択肢が選択されているかを取得します。
void CCComboBoxTestDlg::OnCbnSelchangeComboTest()
{
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_TEST);
int iComboID = pCombo->GetCurSel(); // 選択番号
CString strMes = _T(""); // メッセージボックス出力内容
strMes.Format(_T("%d"), iComboID);
AfxMessageBox(strMes);
}4行目で番号を取得。
後は取得内容をメッセージボックスに出力します。
試しに「3番目の選択肢」を選択すると

番号が取得されました。
ResetContent
コンボボックスの中身を一度削除する処理です。
特記ないので、処理は省略。
終わりに
今回はCComboBoxに関する処理で、
自分が主に使うものを軽くまとめてみました。
DeleteStringとかもありますが、
ちょっと実行エラーが怖くていつも
ResetContent⇒AddString(削除選択肢はAddしない)
の方法とってますね…。
今回はここまでです。

コメント