このページの内容 |
---|
コンボ ボックスとは |
作成方法 |
コンボボックスのインデックスについて |
使い方 |
ありがたいスポンサー様 |
---|
コンボ ボックスは、次のような用途に使います。
具体例として下の図を見てください。これは一般的なフォントの選択ダイアログです。このダイアログは、コンボボックスのオンパレードです。フォントの種類や、スタイル、サイズ、書体の種類にいたるまで、すべてがコンボボックスです。書体の種類が フォントのうちのどれを選ぶかによってリストの内容が変わります。これが上で選択肢は可変だといった理由です。他の場所で選択した内容によって、選択肢が変わるのは、ラジオボタンでは不可能です。
コンボボックスの使用例
また、インターネットエクスプローラーのアドレスバーでも、コンボボックスが使われています。
CreateWindow( "COMBOBOX", "text is here.", // 表示する文字列 ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER, // ウインドウスタイル x, y, // 左上の座標 iWidth, iHeight, // 幅と高さ hParent, // 親ウインドウのウインドウハンドル NULL, // メニューハンドル。NULLでよい。 hInstance, // アプリケーションのインスタンスハンドル。 NULL // ウインドウ作成データ。NULLでよい ) ;
ダイアログエディタで作成する場合には、丸をつけている 『エディットボックス』 で作成できます。
コントロールバーが表示されていない場合は、VC++ のメニューの上で右クリックして、『コントロール』 をチェックすれば出てきます。
ウインドウハンドルを取得するには、hwnd = GetDlgItem( hDlg, IDC_COMBO);といった感じでコントロールIDをしていすればOKです。
インデックスは、ドロップダウンリストを表示させたときに、何番目に表示されるかを表します。コンボボックスのスタイルでソートが有効になっている場合、ソート後に何番目になっているかがインデックスの表す数字です。
動的にアイテムが増減するコンボボックスにおいては、インデックスをいつまでも保持しないように注意しましょう。なぜなら、アイテムが追加されると、インデックスが変化してしまうからです。そのため、間違ったアイテムを削除してしまうことになるかもしれません。
WM_COMMAND を捕まえればよい。代表的なものを次に上げておきます。
CBN_DROPDOWN | ドロップダウンリストが開いたとき |
CBN_CLOSEUP | ドロップダウンリストが閉じられたとき |
CBN_SELCHANGE | 選択項目が変更されたとき |
CBN_EDITUPDATE | 直接入力で内容が変更されたとき。変更内容が表示される前に呼ばれる。 |
CBN_EDITCHANGE | 直接入力で内容が変更されたとき。変更内容が表示された後に呼ばれる。 |
case WM_COMMAND: if(LOWORD(wParam) == IDC_COMBOBOX) { if(HIWORD(wParam) == CBN_DROPDOWN) { // ドロップダウンされたときの処理。 // このときはじめて、コンボボックスに追加していくのもあり。 } else if(HIWORD(wParam) == CBN_CLOSEUP) { } }
CB_ADDSTRING を使うと CBS_SORT が設定されている場合は末尾に、いない場合はソートされて追加します。ソートが有効の場合は、追加するまで何番目に追加されたかが分かりません。この場合、SendMessage の戻り値で、追加されたインデックスを取得することが出来ます。
CB_INSERTSTRING では、追加するインデックスを指定して追加することができます。
// インデックスを考えずに追加する。 // ソートが設定されていなければ、末尾に追加される。 SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)"ほげ"); // インデックスを指定して追加する。 // CBS_SORT が設定されていようがなかろうが、index に追加する。 SendMessage(hwndCombo, CB_INSERTSTRING, index, (LPARAM)"ほげ");
// インデックスによって指定する
SendMessage(hwndCombo, CB_DELETESTRING, index, 0);
専用のメッセージは用意されていません。自力で消していくしかないです。
while(SendMessage(hwndCombo, CB_GETCOUNT, 0, 0) != 0)
{
SendMessage(hwndCombo, CB_DELETESTRING, 0, 0);
}
SendMessage(hwndCombo, CB_GETCOUNT, 0, 0,);
SendMessage(hwndCombo, CB_GETCURSEL, 0, 0,);
// 選択されていない場合は、CB_ERR(-1) が帰ってっくる
SendMessage(hwndCombo, CB_SETCURSEL, index, 0,);
indexがアイテム数よりも多かった場合や -1 であったときは、選択はキャンセルされる。
SendMessage(hwndCombo, CB_SETCURSEL, -1, 0,);
// 選択中 or 編集中のアイテムの場合 // 特定のインデックスの場合 // intIndex 番目の文字列を取得する int intTxtLen = SendMessage(hwndCombo, CB_GETLBTEXTLEN, intIndex, 0); if(intTxtLen != CB_ERR) { char* pszBuf = new char[intTxtLen + 1]; if(SendMessage(hwndCombo, CB_GETLBTEXT, intIndex, (LPARAM)pszBuf) != CB_ERR) { // ここで参照 MessageBox(hDlg, pszBuf, NULL, MB_OK); } delete[] pszBuf; }
// hoge から始まるアイテムのインデックスを indexStart 番目から検索する。 // 大文字小文字は区別しない。 int intIndex = SendMessage(hwndCombo, CB_FINDSTRING, indexStart, "hoge"); // hoge という要素であるアイテムのインデックスを indexStart 番目から検索する。 // 大文字小文字は区別しない。 int intIndex = SendMessage(hwndCombo, CB_FINDSTRINGEXACT, indexStart, "hoge");
もっと複雑な検索を行いたい場合は、ひとつずつ文字列を取得して比較していくしかないでしょう。
SendMessage(hwndCombo, CB_SHOWDROPDOWN, 0, 0);
ドロップダウン の場合(編集できるほう)、文字列のなかでどの文字を選択しているかを CB_GETEDITSEL, CB_SETEDITSEL で取得できます。
実はドロップダウンの場合、編集している部分を表示しているのは、実は エディットボックス ウインドウなのです。そこで、そんなことをしなくても、エディットボックスのウインドウハンドルを取得すれば、もっといろいろ調べることが出来ます。
// ドロップダウンでなければならない
HWND hwndEdit = GetWindow(hwndCombo, GW_CHILD);