コンボ ボックスについて

コンボ ボックスは、編集ボックスまたは静的テキストとリストを組み合わせたものになります。

このトピックは、次のセクションで構成されています。

コンボ ボックスの種類とスタイル

コンボ ボックスは、リストと選択フィールドで構成されます。 一覧には、ユーザーが選択できるオプションが表示され、選択フィールドに現在の選択範囲が表示されます。 選択フィールドが編集コントロールである場合、ユーザーは、リストで使用できない情報を入力できます。そうでない場合、ユーザーはリスト ボックスに含まれる項目を選択することしかできません。

共通コントロール ライブラリには、次の表に示すように、コンボ ボックスの 3 つのメイン スタイルが含まれています。

コンボ ボックスの種類 スタイル定数 説明
シンプル CBS_SIMPLE リストを常に表示し、選択した項目を編集コントロールに表示します。
ドロップダウン CBS_DROPDOWN アイコンがクリックされたときにリストを表示し、編集コントロールで選択した項目を表示します。
ドロップダウン リスト (ドロップダウン リスト) CBS_DROPDOWNLIST アイコンがクリックされたときにリストを表示し、スタティック コントロールで選択した項目を表示します。

 

次のスクリーン ショットは、それぞれ Windows Vista に表示される可能性がある 3 種類のコンボ ボックスを示しています。 最初のスクリーン ショットでは、ユーザーは単純なコンボ ボックスで項目を選択しました。 ユーザーは、このコントロールの編集ボックスに新しい値を入力することもできます。 このリストは Microsoft Visual Studio リソース エディターでサイズが変更されており、2 つの項目を格納するのに十分な大きさです。

screen shot showing an item selected in a simple combo box

2 番目のスクリーン ショットでは、ユーザーがドロップダウン コンボ ボックスの編集コントロールに新しいテキストを入力しました。 ユーザーは既存の項目を選択することもできます。 リスト ボックスは、可能な限り多くの項目に対応するように展開されます。

screen shot showing text typed into a drop-down combo box

3 番目のスクリーン ショットでは、ユーザーがドロップダウン リスト コンボ ボックスを開いています。 リスト ボックスは、可能な限り多くの項目に対応するように展開されます。 ユーザーは新しいテキストを入力できません。

screen shot showing an item selected in a drop-down list combo box

また、特定のプロパティを定義するコンボ ボックス スタイルも多数あります。 コンボ ボックス スタイルは、コンボ ボックスの特定のプロパティを定義します。 スタイルを組み合わせることができます。ただし、一部のスタイルは、特定のコンボ ボックスの種類にのみ適用されます。 コンボ ボックス スタイルの表については、「コンボ ボックス スタイル」を参照してください 。

Note

コンボボックスで視覚スタイルを使用するためには、アプリケーションにマニフェストを含め、プログラムの開始時に InitCommonControls 関数を呼び出す必要があります。 視覚スタイルの詳細については、 視覚スタイルを参照してください。 マニフェストの詳細については、 視覚スタイルを有効にするを参照してください。

 

コンボ ボックスリスト

リストは、ユーザーが選択できる項目を表示するコンボ ボックスの部分です。 通常、アプリケーションはコンボ ボックスを作成するときにリストの内容を初期化します。 ユーザーが選択したリスト アイテムは、 現在の選択です。 複数の項目を選択することはできません。 単純なコンボ ボックスとドロップダウン コンボ ボックスでは、ユーザーはリスト アイテムを選択する代わりに選択フィールドに入力できます。 このような場合、現在の選択は行われず、適切な場合は、アイテムをリストに追加して現在の選択にするのはアプリケーションの責任です。

このセクションでは、次のトピックについて説明します。

現在の選択

現在の選択範囲は、ユーザーが選択したリスト アイテムです。選択したテキストがコンボ ボックスの選択フィールドに表示されます。 ただし、単純なコンボ ボックスまたはドロップダウン コンボ ボックスの場合、現在の選択内容はコンボ ボックス内で使用可能なユーザー入力の 1 つの形式のみです。 ユーザーは選択フィールドにテキストを入力することもできます。

現在の選択は、選択したリスト アイテムの 0 から始まるインデックスによって識別されます。 アプリケーションはいつでも設定および取得できます。 親ウィンドウまたはダイアログ ボックス プロシージャは、ユーザーがコンボ ボックスの現在の選択を変更したときに通知を受け取ります。 アプリケーションが選択を変更しても、親ウィンドウまたはダイアログ ボックスには通知されません。

コンボ ボックスが作成されると、現在の選択は行われません。 これは、ユーザーが選択フィールドの内容を編集した場合の単純なコンボ ボックスまたはドロップダウン コンボ ボックスにも当てはまります。 現在の選択を設定するために、アプリケーションは CB_SETCURSEL メッセージをコンボ ボックスに送信します。 アプリケーションでは、 CB_Standard Edition LECTSTRING メッセージを使用して、現在の選択範囲を、指定した文字列で始まる文字列を持つリスト アイテムに設定することもできます。 現在の選択を決定するために、アプリケーションは CB_GETCURSEL メッセージをコンボ ボックスに送信します。 現在選択されていない場合、このメッセージはCB_ERRを返します。

ユーザーがコンボ ボックス内の現在の選択範囲を変更すると、親ウィンドウまたはダイアログ ボックス プロシージャは、 wParam パラメーターの上位ワードに CBN_SELCHANGE 通知コードを含む WM_COMMAND メッセージを受け取ります。 この通知コードは、 CB_SETCURSEL メッセージを使用して 現在の選択が設定されている場合は送信されません。

ドロップダウン コンボ ボックスまたはドロップダウン リスト ボックスは、ドロップダウン リストが閉じると、 CBN_CLOSEUP 通知コードを親ウィンドウまたはダイアログ ボックス プロシージャに送信します。 ユーザーが現在の選択を変更した場合、ドロップダウン リストが閉じられると、コンボ ボックスによって CBN_SELCHANGE 通知コードも送信されます。 ユーザーがリスト項目を選択するたびに特定のプロセスを実行するには、CBN_SELCHANGE または CBN_CLOSEUP のいずれかの通知コードを処理できます。 通常、CBN_CLOSEUP 通知コードを待ってから現在の選択の変更を処理します。 これは、大量の処理が必要な場合に特に重要です。

アプリケーションは、 CBN_SLENDOK および CBN_SELENDCANCEL 通知コードを処理することもできます。 ユーザーがリスト アイテムを選択するか項目を選択した後にリストを閉じると、システムは、CBN_SELENDOK を送信します。 これは、ユーザーが完了し、選択を処理する必要があることを示します。 CBN_SELENDCANCEL は、ユーザーが項目を選択したときに送信されますが、別のコントロールを選択するか、ドロップダウン リストが開いている間に Esc キーを押すか、ダイアログ ボックスを閉じます。 これは、ユーザーの選択を無視する必要があることを示します。 CBN_SELENDOK は、すべての CBN_SELCHANGE メッセージの前に送信されます。

単純なコンボ ボックスでは、ユーザーがリスト アイテムを ダブルクリックすると、CBN_DBLCLK 通知コードが送信されます。 ドロップダウン コンボ ボックスまたはドロップダウン リストでは、1 回のクリックでリストが非表示になるため、項目をダブルクリックすることはできません。

特定の通知とメッセージは、ドロップダウン リストを含むコンボ ボックスにのみ適用されます。 ドロップダウン リストを開いたり閉じたりすると、コンボ ボックスの親ウィンドウは、 WM_COMMAND メッセージの形式で通知を受け取ります。 リストを開いている場合、 wParam の上位ワードは CBN_DROPDOWN です。 リストが閉じられている場合は、 CBN_CLOSEUPになります。

アプリケーションは、 CB_SHOWDROPDOWN メッセージを使用して、ドロップダウン コンボ ボックスまたはドロップダウン リスト ボックスの一覧を開くことができます。 CB_GETDROPPEDSTATE メッセージを使用してリストが開いているかどうかを判断し、 CB_GETDROPPEDCONTROLRECT メッセージを使用してドロップダウン リストの座標を決定できます。 アプリケーションでは、 CB_SETDROPPEDWIDTH メッセージを使用して、ドロップダウン リストの幅を広げることもできます。

コンテンツの一覧

アプリケーションは、コンボ ボックスを作成するときに、通常、リストに 1 つ以上の項目を追加してコンボ ボックスを初期化します。 後で、アプリケーションはリスト アイテムを追加または削除したり、リストを再初期化したり、リストから項目情報を取得したりできます。

アプリケーションは、 CB_ADDSTRING メッセージを送信してコンボ ボックスにリスト アイテムを追加します。 指定した項目がリストの末尾に追加されるか、並べ替えられたコンボ ボックスで、項目の文字列に基づいて適切な並べ替えられた位置に追加されます。 並べ替えられていないコンボ ボックスでは、アプリケーションは CB_INSERTSTRING メッセージを使用して、特定の位置に項目を挿入できます。 追加されると、リスト アイテムはその位置によって識別されます。

CB_FINDSTRING または CB_FINDSTRINGEXACT メッセージを使用して、アプリケーションはリスト アイテムの位置を決定できます。 CB_FINDSTRING 指定した文字列で始まる文字列を持つ項目を検索します。 CB_FINDSTRINGEXACTは、文字列が文字列と正確に一致する項目を検索します。 どちらのメッセージでも大文字と小文字は区別されません。

アプリケーションは、 CB_DELETESTRING メッセージを使用してリスト アイテムを削除できます。 アプリケーションでコンボ ボックス リストを再初期化する必要がある場合は、最初に CB_RESETCONTENT メッセージを使用して内容全体をクリアできます。 コンボ ボックスが既に表示された後に複数の項目をリストに追加する場合、アプリケーションは再描画フラグをクリアして、各項目が追加された後にコンボ ボックスが再描画されないようにすることができます。 再描画の詳細については、 WM_SETREDRAW メッセージの説明を参照してください。

リスト アイテムに関連付けられている文字列を取得するには、アプリケーションで CB_GETLBTEXT メッセージを使用できます。 項目の文字列は、アプリケーションで指定されたバッファーにコピーされます。 バッファーが文字列を受け取るのに十分な大きさになるように、アプリケーションは最初に CB_GETLBTEXTLEN メッセージを使用して文字列の長さを判断できます。 コンボ ボックス内のリスト アイテムの数を取得するには、アプリケーションで CB_GETCOUNT メッセージを使用できます。

コントロール選択フィールドの編集

アプリケーションは、選択フィールドの内容を取得または設定でき、編集の選択を決定または設定できます。 アプリケーションでは、ユーザーが選択フィールドに入力できるテキストの量を制限することもできます。 選択フィールドの内容が変更されると、通知メッセージが親ウィンドウまたはダイアログ ボックス プロシージャに送信されます。

選択フィールドの内容を取得するために、アプリケーションは WM_GETTEXT メッセージをコンボ ボックスに送信できます。 単純コンボ ボックスまたはドロップダウン コンボ ボックスの選択フィールドの内容を設定するために、アプリケーションはコンボ ボックスに WM_SETTEXT メッセージを送信できます。

編集の選択は、単純コンボ ボックスまたはドロップダウン コンボ ボックスの選択フィールドで、選択したテキストの範囲 (ある場合) です。 アプリケーションは、 CB_GETEDITSEL メッセージを使用して、現在の選択範囲の開始文字位置と終了文字位置を判別できます。 また、 CB_SETEDITSEL メッセージを使用して、編集選択範囲の文字を選択することもできます。

最初に、ユーザーが選択フィールドに入力できるテキストの量は、選択フィールドのサイズによって制限されます。 ただし、コンボ ボックスに CBS_AUTOHSCROLL スタイルがある場合、テキストは選択フィールドのサイズを超えて続行できます。 アプリケーションでは、 CB_LIMITTEXT メッセージを使用して、コントロールに CBS_AUTOHSCROLL スタイルがあるかどうかに関係なく、ユーザーが選択フィールドに入力できるテキストの量を制限できます。

ユーザーが選択フィールドの内容を編集すると、親ウィンドウまたはダイアログ ボックス プロシージャは通知メッセージを受け取ります。 CBN_EDITUPDATE 通知コードが最初に送信され、選択フィールドのテキストが編集されたことを示します。 変更されたテキストが表示されると、システムは CBN_EDITCHANGE を送信します。 リスト アイテムが選択された結果として選択フィールドの内容が変更された場合、これらのメッセージは送信されません。

所有者描画コンボ ボックス

アプリケーションは、リスト アイテムの描画を担当する所有者描画コンボ ボックスを作成できます。 所有者が描画したコンボ ボックス (その所有者) の親ウィンドウは、コンボ ボックスの一部を描画する必要があるときに WM_DRAWITEM メッセージを受信します。 所有者が描画したコンボ ボックスは、テキスト文字列以外の情報を一覧表示できます。 所有者描画コンボ ボックスは、任意の型にすることができます。 ただし、単純コンボ ボックスまたはドロップダウン コンボ ボックスの編集コントロールではテキストのみを表示できますが、所有者はドロップダウン リスト ボックスの選択フィールドを描画します。

所有者描画コンボ ボックスの所有者は、 WM_DRAWITEM メッセージを処理する必要があります。 このメッセージは、コンボ ボックスの一部を再描画する必要があるときに送信されます。 コンボ ボックスに指定されたスタイルによっては、所有者が他のメッセージを処理する必要がある場合があります。

アプリケーションでは、 CBS_OWNERDRAWFIXED または CBS_OWNERDRAWVARIABLE スタイルを指定して、所有者描画コンボ ボックスを作成できます。 コンボ ボックス内のすべてのリスト アイテムが文字列やアイコンなど、同じ高さである場合、アプリケーションは CBS_OWNERDRAWFIXED スタイルを使用できます。 リスト 項目の高さが異なる場合 (サイズの異なるビットマップなど)、アプリケーションは CBS_OWNERDRAWVARIABLE スタイルを使用できます。

所有者描画コンボ ボックスの所有者は、 WM_MEASUREITEM メッセージを処理して、コンボ ボックス内のリスト アイテムのディメンションを指定できます。 アプリケーションが CBS_OWNERDRAWFIXED スタイルを使用してコンボ ボックスを作成した場合、システムは WM_MEASUREITEM メッセージを 1 回だけ送信します。 所有者によって指定されたディメンションは、すべてのリスト アイテムに使用されます。 CBS_OWNERDRAWVARIABLE スタイルが使用されている場合、コンボ ボックスに追加された各リスト アイテムに対して WM_MEASUREITEM メッセージが送信されます。 所有者は、 CB_GETITEMHEIGHT メッセージと CB_Standard Edition TITEMHEIGHT メッセージをそれぞれ使用して、いつでもリスト アイテムの高さを決定または設定できます。

所有者が描画したコンボ ボックスに表示される情報にテキストが含まれている場合、アプリケーションは CBS_HASSTRINGS スタイルを指定することで、各リスト アイテムのテキストを追跡できます。 CBS_SORT スタイルのコンボ ボックスは、このテキストに基づいて並べ替えられます。 コンボ ボックスが CBS_HASSTRINGS スタイルではなく並べ替えられている場合、所有者は WM_COMPAREITEM メッセージを処理する必要があります。

所有者が描画したコンボ ボックスでは、所有者はテキスト以外またはテキストに加えて情報を含むリスト アイテムを追跡する必要があります。 これを行う便利な方法の 1 つは、ハンドルを項目データとして情報に保存することです。 コンボ ボックス内のアイテムに関連付けられているデータ オブジェクトを解放するために、所有者は WM_DELETEITEM メッセージを処理できます。

サブクラス化されたコンボ ボックス

サブクラス化は、アプリケーションがウィンドウに送信または投稿されたメッセージをインターセプトして処理できるようにするプロシージャです。 サブクラス化を使用すると、アプリケーションは特定のメッセージに対して独自の処理を置き換えることができますが、ほとんどのメッセージ処理はクラス定義ウィンドウ プロシージャに任せる必要があります。

オペレーティング システムは、ウィンドウを作成するときに、そのウィンドウに関する情報を、ウィンドウ プロシージャへのポインターを含む内部データ構造に保存します。 ウィンドウをサブクラス化するために、アプリケーションは SetClassLong 関数を呼び出して、そのプロシージャへのポインターをアプリケーション定義サブクラス プロシージャへのポインターに置き換えます。 その後、ウィンドウへのすべてのメッセージがサブクラス プロシージャに送信されます。 次に 、このプロシージャは CallWindowProc 関数を使用して、未処理のメッセージを元のウィンドウ プロシージャに渡します。 CO MB (メガバイト)OBOX クラス ウィンドウ プロシージャによって実行されるメッセージ処理の詳細については、「既定のコンボ ボックスの動作」を参照してください。

コンボ ボックスがダイアログ ボックスの外側にある場合、アプリケーションはサブクラス プロシージャを使用しない限り、TAB キー、Enter キー、ESC キーを処理できません。 単純なコンボ ボックスまたはドロップダウン コンボ ボックスが入力フォーカスを受け取ると、その子編集コントロールにフォーカスがすぐに設定されます。 そのため、アプリケーションでは、単純なコンボ ボックスまたはドロップダウン コンボ ボックスのキーボード入力をインターセプトするために、編集コントロールをサブクラス化する必要があります。 この例については、「コンボ ボックスのサブクラス化」を参照してください。

サブクラス プロシージャが WM_PAINT メッセージを処理する場合は、 BeginPaint 関数を使用して描画を準備する必要があります。 EndPaint 関数を呼び出す前に、デバイス コンテキスト (DC) ハンドルをウィンドウ プロシージャの wParam パラメーターとして渡します。 EndPaint が最初に呼び出された場合、 EndPaint はウィンドウ全体を検証するため、クラス ウィンドウ プロシージャは描画を行いません。

サブクラス化に関連する手法はスーパークラスです。 スーパークラスは、ウィンドウ プロシージャが DefWindowProc を呼び出して未処理のメッセージを処理しない点を除き、他のクラスと似ています。 代わりに、未処理のメッセージを親ウィンドウ クラスのウィンドウ プロシージャに渡します。 ウィンドウ プロシージャ のガイドラインに 従って、 サブクラス化とスーパークラスで発生する可能性のある問題を回避します。