コンボボックス

コンボボックスコントロールはエディットコントロールリストボックスコントロールを組み合わせたようなコントロールです。
リストボックスから項目を選択する機能と、ユーザーが文字を入力する機能を持ち、入力文字をリストボックスに追加する処理をさせることが多いです。

コントロールの作成の基本的なことはボタンコントロールの項を参照してください。

コンボボックスの作成

コンボボックスはCOMBOBOXクラスで作成します。


#define IDC_COMBO1 1000

//コンボボックスに表示するアイテム
const WCHAR* items[] = {
	L"dog",
	L"cat",
	L"rabbit",
	L"fox",
	L"monkey",
	L"hamster"
};

switch (message)
{
case WM_CREATE: //ウィンドウ作成
	CreateWindowEx(
		WS_EX_CLIENTEDGE,
		L"COMBOBOX", NULL,
		WS_CHILD | WS_VISIBLE | WS_VSCROLL,
		10, 10, 280, 120,
		hWnd, (HMENU)IDC_COMBO1, hInst, NULL);

	//コンボボックスにアイテムを追加
	for (int i = 0; i < sizeof(items) / sizeof(items[0]); i++)
	{
		SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)items[i]);
	}
	break;
}

コンボボックスの作成

上部はエディットコントロールのようにキーボード等から文字入力が可能です。
下部はリストボックスのように項目を選択することができ、選択した項目の文字列がエディット部に反映されます。

このコンボボックスは特にスタイルを指定しておらず、これはCBS_SIMPLEというスタイルを指定したものとみなされます。
一般的にコンボボックスと言うとCBS_DROPDOWNスタイルで作成されたものをイメージする人が多いでしょう。


CreateWindowEx(
	WS_EX_CLIENTEDGE,
	L"COMBOBOX", NULL,
	WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWN,
	10, 10, 280, 120,
	hWnd, (HMENU)IDC_COMBO1, hInst, NULL);

ドロップダウン式のコンボボックスの作成

CBS_DROPDOWNスタイルは見た目はエディットコントロールとほぼ同じですが、エディット部の右端にある三角のボタン(▼)を押すことでリストボックスがドロップダウン形式で表示されます。
このスタイルのほうが省スペースなのでよく使用されます。

コンボボックスのスタイル

コンボボックスでは以下のスタイルが使用できます。

定数 説明
CBS_SIMPLE シンプルなコンボボックス(上記参照)
(デフォルト)
CBS_DROPDOWN ドロップダウン形式のコンボボックス(上記参照)
CBS_DROPDOWNLIST エディット部からの入力ができないドロッププダウン形式のコンボボックス
省スペースなリストボックスとして使用できる
CBS_AUTOHSCROLL エディット部の幅を超えた入力を許可し、テキストをスクロールさせる
このスタイルを指定しない場合、エディット部に入力できるテキストの文字数はコンボボックスの幅までに制限される
CBS_OEMCONVERT Unicodeに対応しない古い環境用
(現在は使用しない)
CBS_SORT リストボックスに追加した文字列を自動でアルファベット順に並べ替える
ただしCB_INSERTSTRINGで追加したアイテムの並べ替えは行わない。
CBS_NOINTEGRALHEIGHT コンボボックスのサイズをCreateWindow関数の引数通りに作成する
このスタイルを指定しない場合、高さが足りないために一部しか表示できないアイテムが発生しないようにシステムがコンボボックスのサイズを調整する
CBS_DISABLENOSCROLL 項目数にかかわらずスクロールバーを常に表示する。
(自動で非表示にしない)
CBS_UPPERCASE 入力テキストを自動で大文字に変換する
CBS_LOWERCASE 入力テキストを自動で小文字に変換する
CBS_OWNERDRAWFIXED オーナードローコンボボックスコントロール。
コントロール内の描画をプログラマ自身が行う。
CBS_OWNERDRAWVARIABLE オーナードローコンボボックスコントロール。
コントロール内の描画をプログラマ自身が行う。
CBS_HASSTRINGS アイテムに文字列が含まれている。
オーナードローコンボボックスコントロールで使用する。
それ以外ではこのフラグは既定でオン。

通知コード

コンボボックスを操作するとWM_COMMANDメッセージが発行され、WPARAMの上位ワードに以下の通知コードが送られてきます。

定数 説明
CBN_SELCHANGE リストボックスの選択状態を変更したとき。
すでに選択状態のアイテムを選択した場合にも送信される。
CBN_DBLCLK リストボックスのアイテムをダブルクリックしたとき。
CBS_SIMPLEスタイルのみ。
(ドロップダウンリストのアイテムはダブルクリックできない)
CBN_SETFOCUS フォーカスを受け取ったとき。
CBN_KILLFOCUS フォーカスを失ったとき。
CBN_EDITCHANGE エディット部のテキストが変更される可能性のある操作をしたとき。
テキストの再描画後に送信される。
CBN_EDITUPDATE エディット部のテキストの再描画が行われるとき。
テキストの再描画前に送信される。
CBN_DROPDOWN ドロップダウンリストが表示されるとき。
CBN_CLOSEUP ドロップダウンリストが閉じられるとき。
CBN_SELENDOK アイテムを選択してドロップダウンリストが閉じられるとき。
ドロップダウンリストを展開せずに矢印キーやマウスホイールなどでアイテムを選択するときにも送られる。
CBS_SIMPLEスタイルではアイテムの選択時にCBN_SELENDOKCBN_SELCHANGEの順で送信される。
CBN_SELENDCANCEL ユーザーがアイテムを選択せずにドロップダウンリストが閉じられるとき。
CBS_SIMPLEスタイルでは使用されない。
CBN_ERRSPACE メモリ不足エラー。

コンボボックスのメッセージ

コンボボックスの操作は以下のメッセージをSendMessage関数で送信して行います。

メッセージ WPARAM LPARAM 戻り値
CB_GETEDITSEL 選択範囲の開始位置を受け取るDWORD型のポインタ
(NULLでも可)
選択範囲の終了位置を受け取るDWORD型のポインタ
(NULLでも可)
下位ワード:選択範囲の開始位置
上位ワード:選択範囲の終了位置
エディットコントロールの現在の選択範囲を取得する。
CB_SETEDITSEL 0 下位ワード:選択開始位置
上位ワード:選択終了位置
成功した場合はTRUE
エディットコントロールの選択範囲を設定する。
LPARAMの下位ワードに-1を指定すると選択状態を解除する。
上位ワードに-1を指定するとテキストを全て選択する。
CBS_DROPDOWNLISTスタイルで使用すると戻り値はCB_ERR(-1)になる。
CB_LIMITTEXT 文字数(NULL文字含む) 0 常にTRUE
エディットコントロールに入力可能な最大の文字数を設定する。
WPARAMに0を指定すると32ビット符号あり整数分(約21億)まで。
CBS_AUTOHSCROLLスタイルを指定しない場合、テキストの最大文字数はエディットコントロールの横幅に収まるまでしか設定できない。
メッセージ WPARAM LPARAM 戻り値
CB_ADDSTRING 0 追加する文字列 追加された位置を示すインデックス
エラー発生時はCB_ERR(-1)またはCB_ERRSPACE(-2)
リストボックスの末尾にアイテムを追加する。
CB_INSERTSTRING インデックス 追加する文字列 追加された位置を示すインデックス
エラー発生時はCB_ERR(-1)またはCB_ERRSPACE(-2)
インデックスを指定してリストボックスにアイテムを追加する。
インデックスに-1を指定すると末尾に追加される。
CBS_SORTスタイsルを持つコンボボックスでも並べ替えは行われない。
CB_DELETESTRING インデックス 0 残りのアイテム数
存在しないインデックスを指定した場合はCB_ERR
インデックスを指定してリストボックスからアイテムを削除する。
CB_RESETCONTENT 0 0 常にCB_OKAY(0)
リストボックスの全てのアイテムを削除する。
CB_GETCOUNT 0 0 リストボックスのアイテム数
エラー発生時はCB_ERR
リストボックス内のアイテム数を取得する。
メッセージ WPARAM LPARAM 戻り値
CB_GETCURSEL 0 0 選択中アイテムのインデックス
選択アイテムがない場合はCB_ERR
リストボックスで現在選択中のアイテムのインデックスを取得する。
CB_SETCURSEL インデックス 0 選択されたアイテムのインデックス
存在しないインデックスを指定した場合はCB_ERR
インデックスを指定してリストボックスのアイテムを選択する。
存在しないインデックスを指定した場合は選択が解除される。
(-1などでも可)
CB_SELECTSTRING 検索を開始するインデックス 検索する文字列 見つかったアイテムのインデックス
見つからなかった場合はCB_ERR

指定の文字列から始まるアイテムをリストボックス内から検索し、選択状態にする。
複数ある場合は最初に見つかったものを対象とする。
検索文字列は大文字と小文字を区別しない。
見つからなかった場合は現在の選択状態を変更しない。

検索はWPARAMで指定したインデックスから開始され、最後のアイテムに達すると最初のアイテムに戻り、WPARAMで指定したインデックスまで検索が続行される。
-1を指定するとリストボックス全体を最初から検索する。

CB_FINDSTRING 検索を開始するインデックス 検索する文字列 見つかったアイテムのインデックス
見つからなかった場合はCB_ERR

指定の文字列から始まるアイテムをリストボックス内から検索する。
複数ある場合は最初に見つかったものを対象とする。
検索文字列は大文字と小文字を区別しない。

検索はWPARAMで指定したインデックスから開始され、最後のアイテムに達すると最初のアイテムに戻り、WPARAMで指定したインデックスまで検索が続行される。
-1を指定するとリストボックス全体を最初から検索する。

CB_FINDSTRINGEXACT 検索を開始するインデックス 検索する文字列 見つかったアイテムのインデックス
見つからなかった場合はCB_ERR

指定の文字列と一致するアイテムをリストボックス内から検索する。
複数ある場合は最初に見つかったものを対象とする。
検索文字列は大文字と小文字を区別しない。

検索はWPARAMで指定したインデックスから開始され、最後のアイテムに達すると最初のアイテムに戻り、WPARAMで指定したインデックスまで検索が続行される。
-1を指定するとリストボックス全体を最初から検索する。

CB_GETTOPINDEX 0 0 一番上に表示中のアイテムのインデックス
リストボックスに現在表示されている中で一番上にあるアイテムのインデックスを取得する。
CB_SETTOPINDEX インデックス 0 成功した場合は0
エラー発生時はCB_ERR
インデックスで指定したアイテムができるだけ上部に表示されるようにリストボックスをスクロールする
メッセージ WPARAM LPARAM 戻り値
CB_GETLBTEXT インデックス 文字列を格納するバッファ 取得した文字列の長さ
(NULL文字除く)
存在しないインデックスを指定した場合はCB_ERR
インデックスを指定してリストボックスのアイテムの文字列を取得する。
CB_GETLBTEXTLEN インデックス 0 文字列の長さ
(NULL文字除く)
存在しないインデックスを指定した場合はCB_ERR
インデックスを指定してリストボックスのアイテムの文字列の長さを取得する。
(NULL文字は含まない)
CB_GETLBTEXTメッセージで文字列を取得する前に必要なバッファを確保するのに使用すると良い。
CB_SETITEMDATA インデックス 項目に関連付けられる値 エラー発生時はCB_ERR
インデックスで指定したリストボックスのアイテムに特定の値を関連付ける。
この値はCB_GETITEMDATAで取得できる。
CB_GETITEMDATA インデックス 0 項目に関連付けられている値
インデックスで指定したリストボックスのアイテムに関連付けられている値を取得する。
メッセージ WPARAM LPARAM 戻り値
CB_SHOWDROPDOWN TRUE:表示
FALSE:非表示
0 常にTRUE
ドロップダウンリストボックスの表示状態を設定する。
CB_GETDROPPEDSTATE 0 0 TRUE:表示
FALSE:非表示
ドロップダウン形式のリストボックスで、リストボックスが表示されているか否かを取得する。
CB_SETEXTENDEDUI TRUE:拡張UIを使用する
FALSE:通常UIを使用する
0 成功した場合はCB_OKAY
エラー発生時はCB_ERR
ドロップダウン形式のリストボックスで、拡張UIを使用するかを設定する。
(UI=ユーザーインターフェイス)
通常のUIは、F4キーでドロップダウンリストを開き、矢印キー上下またはマウスホイールで項目を設定する。
拡張UIは、F4キーが無効になり矢印キー上下でドロップダウンリストを開く。
マウスホイールは無効になる。
(開いたリストのスクロールは可能)
CB_GETEXTENDEDUI 0 0 TRUE:拡張UI
FALSE:通常UI
ドロップダウン形式のリストボックスで、拡張UIが使用されているかを取得する。
拡張UIについてはCB_SETEXTENDEDUIを参照。
メッセージ WPARAM LPARAM 戻り値
CB_GETDROPPEDCONTROLRECT 0 RECT構造体へのポインタ 成功した場合は0以外
失敗した場合は0
ドロップダウン形式のリストボックスで、ドロップダウン状態のコンボボックスの座標を取得しRECT構造体に格納する。
CB_SETITEMHEIGHT 高さを設定する部位
(説明を参照)
高さ
(ピクセル単位)
無効な値を指定した場合はCB_ERR
コンボボックスの部品の高さを設定する。
WPARAMには以下の値を指定する。
-1:エディットコントロールの高さの設定。
0:リストボックスアイテムの高さの設定。
CB_GETITEMHEIGHT 高さを取得する部位
(説明を参照)
0 高さ
エラー発生時はCB_ERR
コンボボックスの部品の高さを取得する。
WPARAMには以下の値を指定する。
-1:エディットコントロールの高さを取得。
0:リストボックスアイテムの高さを取得。
CB_SETHORIZONTALEXTENT 水平スクロール可能な幅
(ピクセル単位)
0 なし

リストボックスの水平スクロール可能な幅をピクセル単位で設定する。
リストボックスの幅がこの設定値よりも小さい場合に水平スクロールバーが表示される。
WS_HSCROLLスタイルの指定が必要。

リストボックスはこのメッセージを送信しない限り、水平スクロールバーを表示したりスクロール幅を更新したりしない。

CB_GETHORIZONTALEXTENT 0 0 水平スクロール可能なピクセル数
水平スクロール可能な幅をピクセル単位で取得する。
WS_HSCROLLスタイルの指定が必要。
CB_SETDROPPEDWIDTH 0 0 新しい幅
失敗した場合はCB_ERR
ドロップダウン形式のリストボックスの最小許容幅を設定する。
実際の幅はコンボボックスの幅と最小許容幅の大きい方に設定される。
CB_GETDROPPEDWIDTH 0 0
失敗した場合はCB_ERR
ドロップダウン形式のリストボックスの最小許容幅を取得する。
メッセージ WPARAM LPARAM 戻り値
CB_INITSTORAGE 追加するアイテムの数 アイテムの文字列に割り当てるメモリサイズ
(バイト単位)
メモリに割り当てたアイテムの総数
失敗した場合はCB_ERRSPACE
リストボックスにアイテムを格納するためのメモリをあらかじめ確保する。
大量のアイテムを追加する場合に、そのためのメモリを確報することで処理を高速化できる。
確保したメモリサイズを超える追加があった場合は通常の方法でメモリが確保される。
CB_GETCOMBOBOXINFO 0 COMBOBOXINFO構造体へのポインタ 成功した場合は0以外
失敗した場合は0
コンボボックスに関する情報をCOMBOBOXINFO構造体に格納する。
CB_DIR 検索対象を指定する定数 検索するパス
(絶対パス/相対パス)
最後に追加されたアイテムのインデックス。

エラー発生時はCB_ERRまたはCB_ERRSPACE

パス文字列および指定の属性に一致するファイル名やディレクトリ名を取得しリストボックスに追加する。
パスにはワイルドカードが使用可能。

WPARAMには以下の定数の組み合わせで属性を指定する。
DDL_ARCHIVE:アーカイブファイル
DDL_DIRECTORYサブディレクトリ
DDL_DRIVES:ドライブ
DDL_EXCLUSIVE:指定された属性を持つファイルのみを含むようにする
DDL_HIDDEN:隠しファイル
DDL_READONLY:読み取り専用ファイル
DDL_READWRITE:特別な属性を持たない読み書き可能なファイル(デフォルト)
DDL_SYSTEM:システムファイル