レガシー Windows API(概要)について

ここで紹介しているAPIは、Windows95、Windows NT3.5時代のAPI群であり、最新のAPIは含まれていないことに注しして欲しい。なお、当時の解説書は現在よりもより詳細に解説しているため、参考になるはずである。

  • レイアウトを変換する際、崩れているページがあります。
  • 概要およびSampleコードはありますが、APIの解説はありません。

ご要望があれば旧版のWin32 API(HELP形式)をお譲りします。問い合わせフォームより申し込みください。

Windows API コンボ ボックスの概要

「コンボ ボックス」はCOMBOBOXクラスで定義される特殊な種類のコントロールで、 リスト ボックスとエディット コントロールの両方の機能の多くを組み合わせたものです。Microsoft(R) Win32(R) アプリケーション プログラミング インターフェイス (API)では、 単純なコンボ ボックス (CBS_SIMPLE)、 ドロップダウン コンボ ボックス (CBS_DROPDOWN)、 ドロップダウン リスト ボックス (CBS_DROPDOWNLIST) の3種類のコンボ ボックスを用意しています。

また、 特定のプロパティを定義するコンボ ボックス スタイルも多くあります。たとえば、 「オーナー描画」コンボ ボックスを作成するスタイルを指定することによって、 コントロール内の情報の表示をアプリケーションが担当するようになります。

コンボ ボックスは、 リストと選択フィールドで構成されます。リストはユーザーが選択可能なオプションを表し、 選択フィールドは現在の選択を表示します。ドロップダウン リスト ボックス以外では、 選択フィールドはエディット コントロールで、 リストにないテキストを入力するのに使われます。

コンボ ボックスは、 主にダイアログ ボックスで使われます。ダイアログ ボックスは、 TabEnter Escなどのコンボ ボックスが処理できないキーボード入力メッセージを処理できます。しかし、 ウィンドウをサブクラス化することによって、 この機能をダイアログ ボックス外でも使うことができます。ダイアログ ボックスについて詳しくは、 ダイアログ ボックスの概要を参照してください。

このトピックでは、 コンボ ボックスの種類とスタイル、 コンボ ボックスの各部分、 オーナー描画コンボ ボックスの使い方、 コンボ ボックスのサブクラス化の方法について説明します。また、 コンボ ボックスのそのほかの機能についても説明します。[>>] ボタンを使って以下に示すトピックを順番に読んでください。または、 各トピックをクリックすると、 そのトピックの内容を表示できます。

  • コンボ ボックスの種類とスタイル
  • コンボ ボックス リスト
  • エディット コントロール選択フィールド
  • オーナー描画コンボ ボックス
  • コンボ ボックスのサブクラス化
  • コンボ ボックスの特別な機能
  • コンボ ボックス通知メッセージ
  • コンボ ボックスのデフォルト動作
  • 単純コンボ ボックスの作成
  • オーナー描画コンボ ボックスの作成
  • コンボ ボックスのサブクラス化の方法
  • コンボ ボックス関数とメッセージ

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

コンボ ボックスは、 種類とスタイルで分類されます。コンボ ボックスのリストがドロップダウン リストかどうかや、 選択フィールドがエディット コントロールかどうかは、 コンボ ボックスの種類によって決まります。ドロップダウン リストはユーザーがオープンしたときだけしか表示されないため、 リストを常に表示するよりも画面上の領域が少なくて済みます。選択フィールドがエディット コントロールならば、 ユーザーは、 リストにない情報を入力できます。そうでないときは、 ユーザーはリスト内の項目しか選択できません。

3つのコンボ ボックスの種類と、 それぞれドロップダウン リストやエディット コントロールを持つかどうかを次の表に示します。

コンボ ボックス の種類 ドロップダウン リスト エディット コントロール

単純コンボ ボックス × ○

ドロップダウン コンボ ボックス ○ ○

ドロップダウン リスト ボックス ○ ×

コンボ ボックス スタイルは、 コンボ ボックスの特定のプロパティを定義します。スタイルは組み合わせて使うことができますが、 一部のスタイルは特定の種類のコンボ ボックスにしか適用できません。コンボ ボックス スタイルを次の表に示します。

 

スタイル 説明

CBS_AUTOHSCROLL ユーザーが行の終わりに文字を入力すると、 エディット コントロール内のテキストを自動的に右にスクロールします。このスタイルを指定しなければ、 長方形の境界内に収まるだけのテキストしか入力できません。

CBS_DISABLENOSCROLL ・sXト ボックスにスクロールするための十分な項目が含まれていないときに、 ボックスに使用不能の垂直スクロール バーを表示します。このスタイルを指定しなければ、 リスト ボックスにスクロールするための十分な項目がない場合、 スクロール バーは表示されません。

CBS_DROPDOWN ドロップダウン コンボ ボックスを表示します。

CBS_DROPDOWNLIST ドロップダウン リスト ボックスを表示します。

CBS_HASSTRINGS オーナー描画コンボ ボックスが文字列で構成される項目を含むことを示します。アプリケーションがCB_GETLBTEXTメッセージを使って、 特定の項目に対してテキストを取り出せるように、 コンボ ボックスは文字列のメモリとアドレスを保守します。

CBS_NOINTEGRALHEIGHT コンボ ボックスのサイズを、 アプリケーションがコンボ ボックスを作成するときに指定したとおりのサイズにします。通常、 Windowsは、 項目が中途半端に表示されないように、 コンボ ボックスのサイズを調整します。

CBS_OEMCONVERT コンボ ボックスのエディット コントロールに入力されたテキストを、 Windowsの文字セットからOEM文字セットに変換し、 その後Windows文字セットに変換し直します。これにより、 アプリケーションがCharToOem関数を呼び出してコンボ ボックス内のWindows文字列をOEM文字に変換するときに、 文字が正しく変換できます。このスタイルはファイル名を含むコンボ ボックスに一番役立ち、 CBS_SIMPLEまたはCBS_DROPDOWNスタイルで作成されたコンボ ボックスだけに適用されます。

CBS_OWNERDRAWFIXED リスト ボックスのオーナーがボックスの内容を描画する責任があること、 また、 リスト ボックスの項目はすべて同じ高さであることを示します。オーナー ウィンドウは、 コンボ ボックスが作成されたときにはWM_MEASUREITEMメッセージを受け取り、 コンボ ボックスが視覚的に変更されたときにはWM_DRAWITEMメッセージを受け取ります。

CBS_OWNERDRAWVARIABLE リスト ボックスのオーナーがボックスの内容を描画する責任があること、 また、 リスト ボックスの項目の高さがいろいろ異なることを示します。オーナー ウィンドウは、 コンボ ボックスが作成されたときにはWM_MEASUREITEMメッセージを受け取り、 コンボ ボックスが視覚的に変更されたときにはWM_DRAWITEMメッセージを受け取ります。

CBS_SIMPLE 単純なコンボ ボックスを表示します。

CBS_SORT リストの内容を自動的にソートします。

コンボ ボックス リスト

リストとは、 ユーザーが選択可能な項目を表示する、 コンボ ボックスの一部です。通常、 リストの内容は、 コンボ ボックスを作成するときに初期化します。ユーザーが選択したリスト項目は、 「現在の選択」と呼ばれます。単純コンボ ボックスとドロップダウン コンボ ボックスでは、 ユーザーはリスト項目を選択せずに選択フィールドに情報を入力することもできます。そのような場合、 現在の選択はありません。詳しくは、 「現在の選択」を参照してください。

リストの内容

通常、 コンボ ボックスを作成するときは、 リストに文字列を追加してコンボ ボックスを初期化します。また、 後でリスト項目を追加または削除してリストを再初期化したり、 リストから文字列を取得することができます。

リスト項目をコンボ ボックスに追加するには、 コンボ ボックスにCB_ADDSTRINGメッセージを送ります。指定した文字列は、 リストの最後に追加されます。ソートされるコンボ ボックスでは、 正しくソートされた位置に追加されます。ソートされないコンボ ボックスでは、 CB_INSERTSTRINGメッセージを使って、 特定の位置に文字列を挿入できます。リスト項目を追加したら、 そのリスト項目は位置で識別します。

リスト項目の位置を判断するには、 CB_FINDSTRINGメッセージやCB_FINDSTRINGEXACTメッセージを使います。CB_FINDSTRINGメッセージは、 指定された文字列で始まる項目を検索します。CB_FINDSTRINGEXACTメッセージは、 指定された文字列に正確に一致する項目を検索します。どちらのメッセージも大文字と小文字を区別しません。

リスト項目を削除するには、 CB_DELETESTRINGメッセージを使います。コンボ ボックス リストを再初期化しなければならないときは、 まず、 CB_RESETCONTENTメッセージを使ってコンボ ボックスの内容全体を消去してください。すでに表示されているコンボ ボックスのリストに複数の文字列を追加するときは、 再描画フラグをクリアして、 文字列を追加するたびにコンボ ボックスが再描画されないようにしてください。再描画について詳しくは、 WM_SETREDRAWメッセージを参照してください。

リスト項目のテキストを取得するには、 CB_GETLBTEXTメッセージを使います。文字列は、 アプリケーションが指定したバッファにコピーされます。文字列を取得するのに十分な大きさのバッファを確保するため、 まず、 CB_GETLBTEXTLENメッセージを使って文字列の長さを判断してください。コンボ ボックス内のリスト項目の個数を取得するには、 CB_GETCOUNTメッセージを使ってください。

現在の選択

現在の選択とは、 ユーザーが選択したリスト項目です。選択されているテキストは、 コンボ ボックスの選択フィールド エディット コントロールに表示されます。しかし、 現在の選択は、 コンボ ボックスで可能なユーザー入力の1つにすぎません。ユーザーは、 選択フィールドにテキストを入力することもできます。ドロップダウン リスト ボックスでは、 現在の選択が唯一のユーザー入力です。

現在の選択は、 選択されているリスト項目の0から数えたインデックスで識別されます。現在の選択は、 いつでも設定、 取得できます。コンボ ボックスの現在の選択が変更されると、 親ウィンドウやダイアログ ボックス プロシージャは通知を受け取ります。

コンボ ボックスを作成したときは、 現在の選択はありません。また、 単純コンボ ボックスやドロップダウン コンボ ボックスで選択フィールドの内容をユーザーが編集したときも、 現在の選択はありません。現在の選択を設定するには、 CB_SETCURSELメッセージをコンボ ボックスに送ります。また、 指定した文字列で始まるリスト項目を現在の選択に設定するには、 CB_SELECTSTRINGメッセージを使います。現在の選択を判断するには、 CB_GETCURSELメッセージをコンボ ボックスに送ります。現在の選択がなければ、 このメッセージはCB_ERRを返します。

コンボ ボックスの現在の選択が変更されると、 親ウィンドウやダイアログ ボックス プロシージャは、 wParamパラメータの上位ワードにCBN_SELCHANGE通知コードが設定されたWM_COMMANDメッセージを受け取ります。アプリケーションは、 この通知メッセージに応答することによって、 ユーザーがリスト項目を選択するたびに特定の処理を実行できます。CB_SETCURSELメッセージで現在の選択設定されたときや、 単純コンボ ボックスやドロップダウン コンボ ボックスでユーザーが現在の選択を変更したときは、 この通知は送られません。

ドロップダウン コンボ ボックスやドロップダウン リスト ボックスでは、 ユーザーが新しい項目を選択するまで、 リストをクローズして、 現在の選択の変更を処理するのを待ってください。これは、 多量の処理が必要な場合に役立ちます。たとえば、 選択されているドライブのディレクトリ リストを更新する場合、 ユーザーがドライブを選択した後で、 CBN_SELCHANGEメッセージではなくCBN_CLOSEUPメッセージを処理してディレクトリ リストを更新してください。

また、 CBN_SELENDOKメッセージとCBN_SELENDCANCELメッセージを処理することもできます。ユーザーがリスト項目をクリックしたり、 項目を選択してからリストをクローズすると、 システムは、 CBN_SELENDOKを送ります。この通知は、 ユーザーが選択を終了したため、 その選択を処理しなければならないことを示します。CBN_SELENDCANCELは、 ユーザーが項目を選択してからほかのコントロールを選択するか、 ダイアログ ボックスをクローズすると送られます。この通知は、 ユーザーの選択を無視しなければならないことを示します。単純コンボ ボックスでは、 CBN_SELCHANGEメッセージの前に必ずCBN_SELENDOKが送られます。コンボ ボックスにWS_EX_NOPARENTNOTIFYウィンドウ スタイルが指定されているときは、 システムはCBN_SELENDOKメッセージやCBN_SELENDCANCELメッセージを送りません。

単純コンボ ボックスの場合、 リスト項目をユーザーがダブルクリックすると、 システムはCBN_DBLCLK通知メッセージを送ります。しかし、 ドロップダウン コンボ ボックスやドロップダウン リストでは、 1回のクリックでリストが非表示になるため、 項目をダブルクリックすることはできません。

ドロップダウン リスト

一部の通知やメッセージは、 ドロップダウン リストを含むコンボ ボックスだけに適用されます。ドロップダウン リストをオープンしたりクローズすると、 コンボ ボックスの親ウィンドウは、 WM_COMMANDメッセージによって通知を受け取ります。リストがオープンされるときは、 wParamの上位ワードはCBN_DROPDOWNになります。リストがクローズされるときは、 CBN_CLOSEUPになります。

ドロップダウン コンボ ボックスやドロップダウン リスト ボックスのリストをオープンするには、 CB_SHOWDROPDOWNメッセージを使います。リストがオープンされているかどうかを判断するには、 CB_GETDROPPEDSTATEメッセージを使います。また、 ドロップダウン リストの座標を取得するには、 CB_GETDROPPEDCONTROLRECTメッセージを使います。

エディット コントロール選択フィールド

選択フィールドは、 現在選択されているリスト項目を表示する、 コンボ ボックスの一部です。単純コンボ ボックスやドロップダウン コンボ ボックスでは、 選択フィールドはエディット コントロールで、 リストにないテキストを入力できます。

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

単純コンボ ボックスやドロップダウン コンボ ボックスの内容を取得するには、 WM_GETTEXTメッセージをコンボ ボックスに送ります。選択フィールドの内容を設定するには、 WM_SETTEXTメッセージをコンボ ボックスに送ります。

「編集選択」とは、 単純ダイアログ ボックスやドロップダウン ダイアログ ボックスの選択フィールドで選択されているテキストの範囲です。現在の選択の開始文字位置と終了文字位置を判断するには、 CB_GETEDITSELメッセージを使います。また、 編集選択で文字を選択するには、 CB_SETEDITSELメッセージを使います。

CB_LIMITTEXTメッセージを使うことによって、 選択フィールドにユーザーが入力可能なテキストの量を制限できます。

ユーザーが選択フィールドの内容を編集すると、 親ウィンドウやダイアログ ボックス プロシージャは、 通知メッセージを受け取ります。Windowsは、 まず、 選択フィールド内のテキストが編集されたことを示すCBN_EDITUPDATE通知を送ります。変更されたテキストを表示したら、 Windowsは、 CBN_EDITCHANGEを送ります。リスト項目が選択されたために選択フィールドの内容が変更されたときは、 これらの通知は送られません。

オーナー描画コンボ ボックス

リスト項目の描画を自分で行うには、 「オーナー描画」コンボ ボックスを作成してください。オーナー描画コンボボックスを描画しなければならなくなると、 オーナー描画コンボ ボックスの親ウィンドウまたはダイアログ ボックス (「オーナー」) はWM_DRAWITEMメッセージを受け取ります。オーナー描画コンボ ボックスには、 テキスト文字列以外の情報もリストできます。オーナー描画コンボ ボックスはどの種類にすることもできます。しかし、 単純コンボ ボックスやドロップダウン コンボ ボックスのエディット コントロールにはテキストしか表示できません。ドロップダウン リスト ボックスの選択フィールドはオーナーが描画します。

オーナー描画コンボ ボックスのオーナーは、 WM_DRAWITEMメッセージを処理しなければなりません。このメッセージは、 コンボ ボックスを再描画しなければならなくなると送られます。また、 オーナーは、 コンボ ボックスに指定されているスタイルに応じて、 そのほかのメッセージも処理しなければならない場合があります。

オーナー描画コンボ ボックスを作成するには、 CBS_OWNERDRAWFIXEDスタイルまたはCBS_OWNERDRAWVARIABLEスタイルを指定します。コンボ ボックス内のアイコンや文字列などのリスト項目の高さがすべて同じならば、 CBS_OWNERDRAWFIXEDスタイルを使ってください。さまざまなサイズのビットマップなど、 リスト項目の高さがそれぞれ異なるときは、 CBS_OWNERDRAWVARIABLEスタイルを使ってください。

オーナー描画コンボ ボックス内のリスト項目の寸法を指定するには、 コンボ ボックスのオーナーはWM_MEASUREITEMメッセージを処理してください。CBS_OWNERDRAWFIXEDスタイルを使ってコンボ ボックスを作成すると、 Windowsは、 WM_MEASUREITEMメッセージを一度だけ送ります。CBS_OWNERDRAWVARIABLEスタイルを使うと、 Windowsは、 リスト項目をコンボ ボックスに追加するたびにWM_MEASUREITEMメッセージを送ります。リスト項目の高さを判断したり設定するには、 それぞれCB_GETITEMHEIGHTメッセージとCB_SETITEMHEIGHTメッセージを使います。

オーナー描画コンボ ボックスに表示する情報にテキストが含まれているときは、 CBS_HASSTRINGSスタイルを指定して、 各リスト項目のテキストを管理できます。CBS_SORTスタイルのコンボ ボックスは、 このテキストに基づいてソートされます。ソートされるコンボ ボックスにCBS_HASSTRINGSスタイルを指定しないときは、 オーナーはWM_COMPAREITEMメッセージを処理しなければなりません。

オーナー描画コンボ ボックスの場合、 オーナーは、 テキスト以外の情報も含むリスト項目を管理しなければなりません。情報を管理する方法の1つに、 情報のハンドルを「項目データ」として保存する方法があります。項目データについて詳しくは、 リスト項目に関連付けられているデータを参照してください。コンボ ボックスの項目に関連付けられているデータ オブジェクトを解放するには、 WM_DELETEITEMメッセージを処理してください。

オーナー描画コンボ ボックスの例については、 オーナー描画コンボ ボックスの作成を参照してください。

コンボ ボックスのサブクラス化

サブクラス化とは、 ウィンドウに送られたりポストされるメッセージをアプリケーションが横取りして処理できるようにするための手段です。サブクラス化を使うことによって、 特定のメッセージの処理だけを自分自身の処理で置き換え、 それ以外のメッセージの処理はクラス定義のウィンドウ プロシージャに任せることができます。

オペレーティング システムは、 ウィンドウを作成するとき、 ウィンドウ プロシージャのアドレスなどのウィンドウに関する情報を内部的なデータ構造体に保存します。ウィンドウをサブクラス化するには、 SetClassLong関数を呼び出して、 このプロシージャのアドレスをアプリケーション定義のサブクラス プロシージャのインスタンス アドレスで置き換えます。これによって、 そのウィンドウに対するメッセージは、 すべてサブクラス プロシージャに送られます。サブクラス プロシージャは、 CallWindowProc関数を使って、 処理しなかったメッセージを元のウィンドウ プロシージャに渡します。COMBOBOXクラスのウィンドウ プロシージャが行うメッセージ処理の説明については、 コンボ ボックスのデフォルト動作を参照してください。

アプリケーションは、 コンボ ボックスをダイアログ ボックス外で使うとき、 サブクラス プロシージャを使わなければTab EnterEscなどのキーを処理できません。単純コンボ ボックスやドロップダウン コンボ ボックスは、 入力フォーカスを受け取ると、 すぐにフォーカスを子エディット コントロールに設定します。このため、 単純コンボ ボックスやドロップダウン コンボ ボックスのキーボード入力を横取りするには、 エディット コントロールをサブクラス化しなければなりません。この例については、 コンボ ボックスのサブクラス化の方法を参照してください。

サブクラス プロシージャは、 WM_PAINTメッセージを処理するとき、 BeginPaint関数を使って描画を準備しなければなりません。また、 EndPaint関数を呼び出す前に、 デバイス コンテキスト (DC) ハンドルをwParamパラメータに指定して元のウィンドウ プロシージャを呼び出してください。EndPaintを先に呼び出すと、 ウィンドウ全体が有効化されてしまい、 クラス ウィンドウ プロシージャは描画を行いません。

サブクラスに関連した方法に、 「スーパークラス化」があります。スーパークラスは、 ウィンドウ プロシージャがDefWindowProcを呼び出して未処理メッセージを処理させないことを除いて、 ほかのクラスに似ています。スーパークラスのウィンドウ プロシージャは、 未処理のメッセージを親ウィンドウ クラスのウィンドウ プロシージャに渡します。サブクラス化およびスーパークラス化を行う際は、 それにより発生する問題を避けるため、 ウィンドウ プロシージャの概要で説明しているガイドラインに従ってください。

コンボ ボックスの特別な機能

Win32 APIでは、 ディレクトリ リストをコンボ ボックスに表示したり、 コンボ ボックスのリスト項目にデータを関連付けたり、 ドロップダウン コンボ ボックスやドロップダウン リスト ボックスのキーボード インターフェイスを変更するためのメッセージや関数を用意しています。

ディレクトリ リスト

コンボ ボックスにファイルやサブディレクトリの名前を追加するには、 CB_DIRメッセージをコンボ ボックスに送ります。メッセージのwParamパラメータには追加するファイルの属性を指定し、 lParamパラメータにはファイル指定を定義するテキスト文字列を指すポインタを指定します。

ダイアログ ボックス内では、 DlgDirListComboBox関数を使うこともできます。指定されたファイル名にドライブやパスが含まれていれば、 DlgDirListComboBox関数は、 カレント ドライブや現在のディレクトリを変更し、 ファイル名文字列からドライブやパスを削除します。ディレクトリ名を表示するためのスタティック コントロールがあれば、 この関数はそのコントロールも更新します。それから、 コンボ ボックスの内容をリセットし、 コンボ ボックスにCB_DIRメッセージを送って指定されたファイル名を追加します。

DlgDirListComboBox関数で設定されたコンボ ボックスで選択されているファイル名やディレクトリ名、 ドライブ文字を削除するには、 DlgDirSelectComboBoxEx関数を使ってください。

CB_DIRメッセージ、 DlgDirListComboBox関数、 DlgDirSelectComboBoxEx関数は、 リスト ボックスで使われるLB_DIRメッセージ、 DlgDirList関数、 DlgDirSelectEx関数によく似ています。

リスト項目に関連付けられているデータ

コンボ ボックスのリスト項目には、 データを関連付けることができます。CB_SETITEMDATAメッセージは、 リスト項目にDWORD値を関連付けます。また、 CB_GETITEMDATAメッセージは、 リスト項目に関連付けられている値を取得します。

オーナー描画コンボ ボックスの作成の例では、 項目データを使って、 ドロップダウン リスト ボックス内の各項目に定数を関連付けています。このような一意な値によって、 ソートされた位置にかかわらず、 各項目を識別できます。

また、 項目データを使って、 リスト項目にハンドルやポインタを関連付けることもできます。そのような処理を行う場合は、 WM_DELETEITEMメッセージを処理して、 リスト項目が削除されるときに関連付けられているオブジェクトも削除したり解放してください。

拡張ユーザー インターフェイス

ドロップダウン コンボ ボックスとドロップダウン リスト ボックスは、 「拡張ユーザー インターフェイス」と呼ばれるもう1つのキーボード インターフェイスをサポートしています。デフォルトでは、 F4キーでリストをオープンまたはクローズし、 キーで現在の選択を変更できます。しかし、 拡張ユーザー インターフェイスのコンボ ボックスでは、 F4キーは使用できず、 キーを押すとドロップダウン リストがオープンします。

コンボ ボックスのユーザー インターフェイスを選択するには、 CB_SETEXTENDEDUIメッセージをコンボ ボックスに送ってください。wParamパラメータにTRUEを指定すると、 拡張ユーザー インターフェイスが使用可能になります。FALSEを指定すると、 デフォルトのユーザー インターフェイスが設定されます。コンボ ボックスが拡張ユーザー インターフェイスを使用しているかどうかを判断するには、 CB_GETEXTENDEDUIメッセージをコンボ ボックスに送ります。

コンボ ボックス通知メッセージ

コンボ ボックスからのメッセージは、 WM_COMMANDメッセージによる通知として送られます。通知メッセージはwParamパラメータに格納されています。アプリケーションは、 次に示すコンボ ボックス通知メッセージを処理できます。

通知メッセージ 説明

CBN_CLOSEUP ドロップダウン コンボ ボックスまたはドロップダウン リスト ボックスのリストがクローズしようとしていることを示します。

CBN_DBLCLK 単純コンボ ボックス内のリスト項目をユーザーがダブルクリックしたことを示します。

CBN_DROPDOWN ドロップダウン コンボ ボックスまたはドロップダウン リスト ボックスのリストがオープンしようとしていることを示します。

CBN_EDITCHANGE 単純コンボ ボックスまたはドロップダウン コンボ ボックスのエディット コントロールのテキストをユーザーが変更したことを示します。この通知メッセージは、 変更されたテキストが表示された後で送られます。

CBN_EDITUPDATE 単純コンボ ボックスまたはドロップダウン コンボ ボックスのエディット コントロールのテキストをユーザーが変更したことを示します。この通知メッセージは、 変更されたテキストが表示される前に送られます。

CBN_ERRSPACE リスト項目の追加などの要求された処理を実行するためのメモリをコンボ ボックスが割り当てられなかったことを示します。

CBN_KILLFOCUS コンボ ボックスが入力フォーカスを失おうとしていることを示します。

CBN_SELCHANGE 現在の選択が変更されたことを示します。

CBN_SETFOCUS コンボ ボックスが入力フォーカスを取得しようとしていることを示します。

コンボ ボックスのデフォルト動作

ここでは、 定義済みのCOMBOBOXクラス ウィンドウ プロシージャが処理するメッセージを表にして説明します。

メッセージ 説明

CB_ADDSTRING リスト ウィンドウにLB_ADDSTRINGメッセージを送ってリスト項目を追加します。

CB_DELETESTRING リスト ウィンドウにLB_DELETESTRINGメッセージを送ってリスト項目を削除します。

CB_DIR 指定された属性とパスに一致するファイル名をリストに追加します。

CB_FINDSTRING リスト ウィンドウにLB_FINDSTRINGメッセージを送ります。このメッセージは、 指定されたテキストで始まる最初のリスト項目のインデックスを返します。

CB_FINDSTRINGEXACT リスト ウィンドウにLB_FINDSTRINGメッセージを送ります。このメッセージは、 指定されたテキストに正確に一致する最初のリスト項目のインデックスを返します。

CB_GETCOUNT リスト ウィンドウにLB_GETCOUNTメッセージを送ります。このメッセージは、 リスト項目の個数を返します。

CB_GETCURSEL リスト ウィンドウにLB_GETCURSELメッセージを送ります。このメッセージは、 現在選択されている項目のインデックスを返します。

CB_GETDROPPEDCONTROLRECT

指定された長方形構造体に、 ドロップダウン リストのスクリーン座標を設定します。

CB_GETDROPPEDSTATE ドロップダウン リストがオープンされていればTRUEを返します。そうでないときは、 FALSEを返します。

CB_GETEDITSEL エディット コントロールにEM_GETSELメッセージを送り、 現在の選択の開始位置と終了位置を返します。ドロップダウン リスト ボックスの場合は、 ウィンドウ プロシージャはCB_ERRを返します。

CB_GETEXTENDEDUI コンボ ボックスがドロップダウン コンボ ボックスかドロップダウン リスト ボックスで、 拡張ユーザー インターフェイス フラグがセットされていればTRUEを返します。そうでないときは、 黌FALSEを返します。

CB_GETITEMDATA リスト ウィンドウにLB_GETITEMDATAメッセージを送ります。このメッセージは、 指定されたリスト項目に関連付けられている32ビット値を返します。

CB_GETITEMHEIGHT リスト ウィンドウにLB_GETITEMHEIGHTメッセージを送ります。このメッセージは、 指定されたオーナー描画リスト項目のピクセル単位の高さを返します。

CB_GETLBTEXT リスト ウィンドウにLB_GETTEXTメッセージを送ります。このメッセージは、 指定されたリスト テキストを指定されたバッファにコピーします。

CB_GETLBTEXTLEN リスト ウィンドウにLB_GETTEXTLENメッセージを送ります。このメッセージは、 指定されたリスト テキストのバイト単位の長さを返します。

CB_GETLOCALE リスト ウィンドウにLB_GETLOCALEメッセージを送ります。このメッセージは、 リストの現在のロケールを返します。

CB_INSERTSTRING リスト ウィンドウにLB_INSERTSTRINGメッセージを送ります。このメッセージは、 指定された位置にリスト項目を挿入します。

CB_LIMITTEXT エディット コントロールにEM_LIMITTEXTメッセージを送ります。このメッセージは、 ユーザーがエディット コントロールに入力可能な最大文字数を設定します。ドロップダウン リスト ボックスの場合は、 ウィンドウ プロシージャはCB_ERRを返します。

CB_RESETCONTENT リスト ウィンドウにLB_RESETCONTENTメッセージを送り、 リストの内容を削除します。

CB_SELECTSTRING リスト ウィンドウにLB_SELECTSTRINGメッセージを送ります。このメッセージは、 指定されたテキストで始まる最初のリスト項目を選択します。

CB_SETCURSEL リスト ウィンドウにLB_SETCURSELメッセージを送って、 現在の選択を設定します。

CB_SETEDITSEL エディット コントロールにEM_SETSELメッセージを送ります。このメッセージは、 指定された範囲のテキストを選択します。ドロップダウン リストの場合は、 ウィンドウ プロシージャはCB_ERRを返します。

CB_SETEXTENDEDUI 拡張ユーザー インターフェイス フラグをセットまたはクリアします。このフラグは、 ドロップダウン コンボ ボックスやドロップダウン リスト ボックスのリストをオープンしたりクローズするキーを変更します。コンボ ボックスが単純コンボ ボックスならば、 ウィンドウ プロシージャはCB_ERRを返します。

CB_SETITEMDATA リスト ウィンドウにLB_SETITEMDATAメッセージを送ります。このメッセージは、 指定された32ビット値をリスト項目に関連付けます。

CB_SETITEMHEIGHT リスト ウィンドウにLB_SETITEMHEIGHTメッセージを送ります。このメッセージは、 指定されたオーナー描画リスト項目または選択フィールドの高さを設定します。

CB_SETLOCALE リスト ウィンドウにLB_SETLOCALEメッセージを送り、 リストの現在のロケールを設定します。ロケールは、 CBS_SORTスタイルのリストにCB_ADDSTRINGを使って文字列を追加したときのソート方法に影響します。

CB_SHOWDROPDOWN ドロップダウン リストを表示または非表示にします。このメッセージは、 単純コンボ ボックスには効果はありません。

WM_CHAR 文字入力を処理します。ドロップダウン リスト ボックスの場合は、 このメッセージはリスト ウィンドウに渡され、 指定された文字で始まる最初の項目に選択が移動します。単純コンボ ボックスやドロップダウン コンボ ボックスの場合は、 このメッセージはエディット コントロールに送られます。

WM_CLEAR 編集選択を削除します。単純コンボ ボックスやドロップダウン コンボ ボックスの場合は、 エディット コントロールがこのメッセージを処理します。ドロップダウン リスト ボックスの場合は、 ウィンドウ プロシージャはCB_ERRを返します。

WM_COMMAND エディット コントロールやリスト ウィンドウからの通知メッセージを処理し、 対応するコンボ ボックス通知メッセージを親ウィンドウに送ります。

エディット コントロール通知の場合、 ウィンドウ プロシージャは、 リスト ウィンドウの現在の選択、 キャレット インデックス、 およびいちばん上のインデックスを更新します。リスト通知の場合は、 ウィンドウ プロシージャは選択フィールドの内容を更新します。

WM_COMPAREITEM メッセージを親ウィンドウに渡して、 オーナー描画リスト項目の相対的なソート位置をアプリケーションが指定できるようにします。コンボ ボックス ウィンドウは、 リスト ウィンドウからこのメッセージを受け取ります。

WM_COPY 編集選択をクリップボードにコピーします。単純コンボ ボックスやドロップダウン コンボ ボックスの場合は、 エディット コントロールがこのメッセージを処理します。ドロップダウン リスト ボックスの場合は、 ウィンドウ プロシージャはCB_ERRを返します。

WM_CREATE コンボ ボックスを初期化します。

WM_CUT 編集選択を削除してクリップボードにおきます。単純コンボ ボックスやドロップダウン コンボ ボックスの場合は、 エディット コントロールがこのメッセージを処理します。ドロップダウン リスト ボックスの場合は、 ウィンドウ プロシージャはCB_ERRを返します。

WM_DELETEITEM メッセージを親ウィンドウに渡して、 リスト項目が削除されたことをアプリケーションに通知します。コンボ ボックス ウィンドウは、 リスト ウィンドウからこのメッセージを受け取ります。

WM_DRAWITEM メッセージを親ウィンドウに渡して、 指定されたリスト項目をアプリケーションが描画するようにします。コンボ ボックス ウィンドウは、 リスト ウィンドウからこのメッセージを受け取ります。また、 ウィンドウ プロシージャは、 このメッセージを自分で発行して、 ドロップダウン リスト ボックスの選択フィールドをアプリケーションに描画させることができます。

WM_ENABLE マウス入力やキーボード入力を使用可能または使用不能にします。

WM_ERASEBKGND 背景が消去されたことを示す1を返します。

WM_GETDLGCODE DLG_WANTCHARSとDLGC_WANTARROWSの組み合わせを返します。

WM_GETFONT コンボ ボックスがテキストを描画するときの現在のフォントのハンドルを返します。

WM_GETTEXT 選択フィールドの内容を指定されたバッファにコピーします。単純コンボ ボックスやドロップダウン コンボ ボックスの場合は、 エディット コントロールがこのメッセージを処理します。

WM_GETTEXTLENGTH 選択フィールド内のテキストの文字単位の長さを返します。単純コンボ 黌 ボックスやドロップダウン コンボ ボックスの場合は、 エディット コントロールがこのメッセージを処理します。

WM_KEYDOWN 文字以外のキーボード入力を処理します。ドロップダウン リスト ボックスの場合、 このメッセージはリスト ウィンドウに渡されます。リスト ウィンドウではウィンドウ自身が表示されたりされなかったり、 または現在の選択やキャレット インデックスの変更が行われます。単純コンボ ボックスやドロップダウン コンボ ボックスの場合は、 エディット コントロールがこのメッセージを処理します。エディット コントロールは、 キー、 キー、 F4キーなどの特定のキーをリスト ウィンドウに渡します。

WM_KILLFOCUS 選択フィールドの強調表示を解除し、 必要ならば、 ドロップダウン リストをクローズします。入力フォーカスを取得しようとしているウィンドウがコンボ ボックスの一部 (エディット コントロールなど) ならば、 このメッセージは無視されます。

WM_LBUTTONDBLCLK WM_LBUTTONDOWNと同じです。

WM_LBUTTONDOWN コンボ ボックスにフォーカスを設定します。また、 ドロップダウン コンボ ボックスやドロップダウン リスト ボックスの場合は、 リストをオープンまたはクローズします。リストをオープンする場合、 ウィンドウ プロシージャはマウスをキャプチャして、 マウス ボタンをドラッグして離すことによって選択できるようにします。

WM_LBUTTONUP マウスでリストがオープンされたときに、 マウス キャプチャを解放します。

WM_MEASUREITEM 親ウィンドウにメッセージをポストして、 指定されたMEASUREITEMSTRUCT構造体の内容をアプリケーションが修正できるようにします。コンボ ボックス ウィンドウは、 リスト ウィンドウからこのメッセージを受け取ります。

WM_MOUSEMOVE マウスでリストがオープンされ、 マウス ボタンがまだ押されているときは、 リスト ウィンドウにメッセージをポストします。これによって、 ユーザーは、 リスト項目にマウス ポインタをドラッグしてボタンを離して項目を選択できます。

WM_NCCREATE コンボ ボックス ウィンドウ プロシージャが使用する内部データ構造体を割り当てます。

WM_NCDESTROY WM_NCCREATEメッセージで割り当てられたリソースを解放します。

WM_PAINT コンボ ボックスの無効リージョンを描画します。wParamがNULL以外ならば、 DCハンドルがサブクラス関数から渡されていることが仮定されます。ウィンドウ プロシージャは、 BeginPaintEndPaintを呼び出さずに、 指定されたDCを使用します。

WM_PASTE 編集選択をクリップボードの内容で置き換えます。単純コンボ ボックスやドロップダウン コンボ ボックスの場合は、 エディット コントロールがこのメッセージを処理します。ドロップダウン リスト ボックスの場合は、 ウィンドウ プロシージャはCB_ERRを返します。

WM_SETFOCUS エディット コントロールにフォーカスを設定します。ドロップダウン リスト ボックスの場合は、 選択フィールドを反転表示して、 リスト ウィンドウにキャレットを表示します。

WM_SETFONT 指定されたフォント ハンドルを内部構造体に保存して、 選択フィールドとリストの寸法を調整し、 コンボ ボックス ウィンドウを無効化します。選択フィールドやリストのテキストは、 このときに保存されたフォントで表示されます。

WM_SETREDRAW 再描画フラグをセットまたはクリアします。再描画フラグがクリアされていれば、 再描画フラグが再びセットされるまでコンボ ボックスは描画されません。

WM_SETTEXT エディット コントロールの内容を設定します。単純コンボ ボックスやドロップダウン コンボ ボックスの場合は、 エディット コントロールがこのメッセージを処理します。ドロップダウン リスト ボックスの場合は、 ウィンドウ プロシージャはCB_ERRを返します。

WM_SIZE 必要ならば、 子ウィンドウのサイズを変更します。

WM_SYSKEYDOWN 黌ユーザーが押した方向キーに応じて、 ドロップダウン リストをオープンまたはクローズします。

上記以外のメッセージは、 すべてDefWindowProc関数に渡され、 デフォルトの処理が行われます。

コンボ ボックスの使用

ここでは、 次に示すタスクの実行方法を説明しています。[>>] ボタンを使って次に示すトピックを順番に読んでください。または各トピックをクリックすると、 そのトピックの内容が表示されます。

ダイアログ ボックス内での単純コンボ ボックスの作成

ダイアログ ボックス内でのオーナー描画コンボ ボックスの作成

ダイアログ ボックス外での使用のためのコンボ ボックスのサブクラス化

単純コンボ ボックスの作成

ここでは、 ダイアログ ボックス内で単純コンボ ボックスを使用する方法について説明します。各トピックをクリックすると、 そのトピックの内容が表示されます。

ダイアログ ボックスの作成

WM_INITDIALOGメッセージとWM_DESTROYメッセージの処理

[Spell] ダイアログ ボックスの作成

[Spell]ダイアログ ボックスの作成のコード例では、 スペル チェッカのダイアログ ボックスで単純コンボ ボックスを使用しています。スペル チェッカは、 スペルが間違っている単語を発見すると、 代替スペルを提案します。ユーザーは、 スペルの間違いを無視するか、 提案されたスペルのいずれかに変更することができます。また、 提案されていないスペルを入力することもできます。単純コンボ ボックスは、 このようなユーザー入力に適しています。

ダイアログ ボックスの作成

ダイアログ ボックス テンプレートは、 コンボ ボックスのウィンドウ スタイル、 コンボ ボックスのコントロール識別子を定義します。この例では、 コンボ ボックスには、 CBS_SIMPLECBS_SORTWS_VSCROLLWS_TABSTOPのスタイルが使われています。

また、 ダイアログ ボックスには、 [Change](IDOK)、 [Ignore](IDSKIP)、 [Cancel](IDCANCEL)の3つのボタンがあります。定数のIDOKとIDCANCELは、 Win32 APIで定義されています。定数IDSKIPは、 アプリケーションのヘッダー ファイルで定義されています。コントロール識別子のIDCOMBOもアプリケーションのヘッダー ファイルで定義されています。

ダイアログ ボックスについて詳しくは、 ダイアログ ボックスの概要を参照してください。

WM_INITDIALOGメッセージとWM_DESTROYメッセージの処理

ダイアログ ボックス コントロールでイベントが発生すると、 そのコントロールはダイアログ ボックス プロシージャにWM_COMMANDメッセージを送ります。wParam パラメータの上位ワードは通知コードで、 発生したイベントの種類を示します。wParam の下位ワードは、 コントロールを識別する定数です。lParam パラメータは、 コントロールのウィンドウ ハンドルです。

WM_COMMANDメッセージを処理する場合、 スペル チェッカの例が wParam パラメータの下位ワードにあるコントロール識別子を調べて、 メッセージの発信元を判定します。IDCOMBO、 IDOK、 IDSKIP、 IDCANCELという定数が、 コンボ ボックス、 [Change]ボタン、 [Ignore]ボタン、 [Cancel]ボタンのそれぞれのコントロールを識別します。IDOKとIDCANCELは、 WINDOWS.Hで定義されます。ほかの定数はアプリケーションのヘッダー ファイルで定義されます。

コンボ ボックスはいろいろな理由でWM_COMMANDメッセージを送ります。ダイアログ ボックスはイベントの種類を判定するために、 wParam の上位ワードにある通知コードを調べます。この例では、 CBN_DBLCLKM通知メッセージだけを処理します。このメッセージは、 ユーザーがリスト項目をダブルクリックしたときに送られます。ダイアログ ボックス プロシージャは、 [Change]ボタンをクリックしたときと同じ方法で、 この通知メッセージを処理します。

この例で使われているボタンは、 ユーザーがボタンを選択したときにだけ、 WM_COMMANDメッセージを送ります。ユーザーが[Change]ボタンを選択すると、 ダイアログ ボックス プロシージャは、 アプリケーションのエディット コントロール内の現在の選択を、 コンボ ボックスの選択フィールドの内容に置き換えます。選択フィールドには選択されたリスト項目またはユーザーが入力したテキストが含まれます。次にダイアログ ボックス プロシージャは、 [Ignore]ボタンがクリックされたときと同様に、 スペルが間違っている次の言葉を選択します。

ユーザーが[Ignore]ボタンを選択すると、 ダイアログ ボックス プロシージャはアプリケーション定義のSelectNextWord関数とInitSpellList関数を呼び出して、 アプリケーションのエディット コントロール内のスペルが間違っている次の単語を選択します。InitSpellList関数は、 コントロール ボックスの選択フィールドにスペルが間違っている単語を設定し、 提案するスペルをコンボ ボックス リストに追加します。

ユーザーが[Cancle]ボタンを選択すると、 ダイアログ ボックス プロシージャはEndDialog関数を呼び出して、 ダイアログ ボックスをクローズします。

[Spell]ダイアログ ボックスの作成

スペル チェッカ ダイアログ ボックスのダイアログ ボックス プロシージャと補助関数を次に示します。

HWND hwndMain;
HWND hwndEdit;
char achTemp[256]; /* temporary buffer */

LPSTR lpstrDict; /* buffer for dictionary file */
LPSTR *paLpDict; /* array of pointers to words */
UINT cWords; /* number of words */

/********************************************************

FUNCTION: SpellDlgProc

PURPOSE: Dialog procedure for Spell dialog box.

*********************************************************/

BOOL CALLBACK SpellDlgProc(hwndDlg, msg, wParam, lParam)
HWND hwndDlg;
UINT msg;
WPARAM wParam;
LPARAM lParam;
{
switch (msg) {
case WM_INITDIALOG:
if (!OpenDictionary()) {
EndDialog(hwndDlg, 0);
break;
}
SendMessage(hwndEdit, EM_SETSEL, 0, 0);
do
if (!SelectNextWord(hwndEdit, achTemp)) {
GlobalFree((HGLOBAL) lpstrDict);
LocalFree((HLOCAL) paLpDict);
EndDialog(hwndDlg, 0);
break;
}
while (!InitSpellList(
GetDlgItem(hwndDlg, IDCOMBO), achTemp));
break;

case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDCOMBO:
if (HIWORD(wParam) != CBN_DBLCLK)
break;

/* For a double-click, process the OK case. */

case IDOK:
SendDlgItemMessage(hwndDlg, IDCOMBO,
WM_GETTEXT, sizeof(achTemp),
(LPARAM) achTemp);
SendMessage(hwndEdit, EM_REPLACESEL, 0,
(LPARAM) achTemp);

/* Fall through to get the next word. */

case IDSKIP:
do
if (!SelectNextWord(hwndEdit, achTemp)) {
EndDialog(hwndDlg, 0);
break;
}
while (!InitSpellList(GetDlgItem(hwndDlg,
IDCOMBO), achTemp));
break;

case IDCANCEL:
EndDialog(hwndDlg, 0);
}
break;

case WM_DESTROY:
GlobalFree((HGLOBAL) lpstrDict);
LocalFree((HLOCAL) paLpDict);
break;

default:
return FALSE;
}
return TRUE;
}


/********************************************************

FUNCTION: InitSpellList

PURPOSE: Initializes the selection field and list
of suggestions for the specified word, if
it is not in the dictionary.

RETURNS: If the list is initialized, the return
value is TRUE. If an error occurs or the
word is in the dictionary, the return
value is FALSE.

*********************************************************/

BOOL PASCAL InitSpellList(HWND hwndCombo, LPSTR lpszWord)
{
int min = 0; /* beginning of search range */
int max = cWords; /* end of search range */
int n; /* index of word */
int cmp; /* result of comparison */
char ch; /* first character in word */

ch = *lpszWord;
AnsiLowerBuff(&ch, 1);

/*
* Perform a binary search for the word.
*
* The global array paLpDict contains pointers to words
* in the global array lpstrDict. These two variables are
* initialized by the OpenDictionary function.
*/

n = max / 2;
while (min < max) {
cmp = lstrcmpi(lpszWord, paLpDict[n]);
if (cmp == 0)
return FALSE; /* not misspelled */

if (cmp < 0)
max = n;
else
min = n + 1;
n = (min + max) / 2;
}

/* List the words beginning with the same letter as lpszWord. */

SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
while (n > 0 && *paLpDict[n - 1] == ch)
n--;
while (*paLpDict[n] == ch)
SendMessage(hwndCombo, CB_ADDSTRING,
0, (LPARAM) paLpDict[n++]);

/* Place the word in the selection field. */

SendMessage(hwndCombo, WM_SETTEXT, 0, (LPARAM) lpszWord);

return TRUE;
}

オーナー描画コンボ ボックスの作成

ここでは、 オーナー描画コンボ ボックスを使用する方法を説明します。[Square Meal]ダイアログ ボックスの作成のコード例では、 オーナー描画ドロップダウン リスト ボックスを使って、 ビットマップと名前で表現された4つの食べ物のグループを表示しています。食べ物のグループを選択すると、 そのグループの食べ物がリストに表示されます。

ダイアログ ボックスの作成

ダイアログ ボックス テンプレートは、 ウィンドウ スタイル、 ボタン、 コンボ ボックスのコントロール識別子を定義します。この例では、 コンボ ボックスには、 CBS_DROPDOWNLIST CBS_OWNERDRAWFIXEDCBS_SORTCBS_HASSTRINGS
WS_VSCROLL
WS_TABSTOPのスタイルが使われています。

また、 ダイアログ ボックスには、 リスト ボックス (IDLIST) と、 [OK](IDOK) と[Cancel](IDCANCEL) の2つのボタンがあります。定数のIDOKとIDCANCELは、 Win32 APIで定義されています。定数IDLISTは、 アプリケーションのヘッダー ファイルで定義されています。コントロール識別子のIDCOMBOもアプリケーションのヘッダー ファイルで定義されています。

ダイアログ ボックスについて詳しくは、 ダイアログ ボックスの概要を参照してください。

WM_INITDIALOGメッセージとWM_DESTROYメッセージの処理

通常、 ダイアログ ボックス内でコンボ ボックスを使用するときは、 WM_INITDIALOGメッセージを処理するときにコンボ ボックスを初期化します。[Square Meal]ダイアログ ボックスの作成のコード例では、 オーナー描画コンボ ボックスで使われるビットマップをロードしてから、 アプリケーション定義のInitGroupList関数を呼び出してコンボ ボックスを初期化します。また、 コンボ ボックスの最初のリスト 項目を選択してから、 アプリケーション定義のInitFoodList関数を呼び出してリスト ボックスを初期化します。

このコード例では、 オーナー描画コンボ ボックスは、 4つの食べ物の各グループの名前を含むドロップダウン リスト ボックスです。InitGroupListは、 各食べ物グループの名前を追加し、 アプリケーション定義のSetItemDataを呼び出して、 対応する食べ物グループを識別する定数を各リスト項目に関連付けます。

リスト ボックスは、 選択されている食べ物グループの食べ物の名前を含みます。InitFoodListは、 リスト ボックスの内容をリセットしてから、 食べ物グループ ドロップダウン リスト ボックスで現在選択されている食べ物の名前を追加します。

ダイアログ ボックス プロシージャは、 WM_DESTROYメッセージを処理するときに、 オーナー描画コンボ ボックスのビットマップを削除します。

WM_MEASUREITEMメッセージの処理

オーナー描画コンボ ボックスは、 WM_MEASUREITEMメッセージを親ウィンドウやダイアログ ボックス プロシージャに送って、 アプリケーションが各リスト項目の寸法を設定できるようにします。この例のコンボ ボックスはCBS_OWNERDRAWFIXEDスタイルを持っているため、 システムは、 WM_MEASUREITEMメッセージを一度だけ送ります。CBS_OWNERDRAWVARIABLEスタイルを持つコンボ ボックスは、 各リスト項目についてWM_MEASUREITEMメッセージを送ります。

lParamパラメータは、 コントロールとリスト項目を識別するMEASUREITEMSTRUCT構造体を指すポインタです。また、 この構造体は、 リスト項目のデフォルトの寸法も含んでいます。[Square Meal]ダイアログ ボックスの作成のコード例では、 itemHeightメンバを修正して、 食べ物グループのビットマップが収まるようにリスト項目の高さを調整します。

WM_DRAWITEMメッセージの処理

オーナー描画コンボ ボックスは、 リスト項目をアプリケーションに再描画させなければならなくなると、 WM_DRAWITEMメッセージを親ウィンドウまたはダイアログ ボックス プロシージャに送ります。lParamパラメータは、 コントロールとリスト項目を識別するDRAWITEMSTRUCT構造体を指すポインタです。また、 この構造体は、 項目の描画に必要な情報も含んでいます。

[Square Meal]ダイアログ ボックスの作成のコード例では、 食べ物グループに関連付けられているリスト項目のテキストとビットマップを表示しています。項目にフォーカスがあるときは、 フォーカス長方形を描画します。テキストを表示する前に、 選択されている項目に基づいて、 前景色と背景色を設定します。コンボ ボックスはCBS_HASSTRINGSスタイルを持っているため、 コンボ ボックスは各リスト項目のテキストを管理します。このテキストは、 CB_GETLBTEXTメッセージを使って取得できます。

リスト項目に使われるビットマップは、 食べ物グループによって異なります。InitGroupListは、 CB_SETITEMDATAメッセージを使って、 対応する食べ物グループを識別する定数を各リスト項目に関連付けます。ウィンドウ プロシージャは、 DRAWITEMSTRUCT構造体のitemDataメンバが示す値を使って、 表示するビットマップを判断します。システムは、 各食べ物グループのシンボルについて2つのビットマップを使います。イメージの後ろの不規則なリージョンを消去するSRCANDラスタ オペレーションで使われるモノクロ ビットマップと、 イメージを描画するSRCPAINTラスタ オペレーションで使われるカラー ビットマップです。

WM_COMMANDメッセージの処理

ダイアログ ボックス コントロールでイベントが発生すると、 そのコントロールは、 WM_COMMANDメッセージでダイアログ ボックス プロシージャに通知します。[Square Meal]ダイアログ ボックスの作成のコード例では、 コンボ ボックス、 リスト ボックス、 [OK]ボタンからの通知メッセージを処理します。コントロール識別子はwParamの下位ワードで渡され、 通知コードはwParamの上位ワードで渡されます。

コントロール識別子がIDCOMBOならば、 イベントはコンボ ボックスで発生しています。この場合、 ダイアログ ボックスは、 現在の選択が変更されたことを示すCBN_SELCHANGE以外のコンボ ボックス イベントをすべて無視します。ダイアログ ボックス プロシージャは、 InitFoodListを呼び、 出してリスト ボックスの内容をリセットし、 ドロップダウン リスト ボックスの現在の選択の名前を追加します。

コントロール識別子がIDLISTならば、 イベントはリスト ボックスで発生しています。この場合、 ダイアログ ボックス プロシージャは、 ユーザーがリスト項目をダブルクリックしたことを示すLBN_DBLCLK以外のリスト ボックス イベントをすべて無視します。このイベントは、 [OK]ボタンのクリックと同様に処理されます。

コントロール識別子がIDOKならば、 ユーザーが[OK]ボタンをクリックしたことを示しています。この場合、 ダイアログ ボックス プロシージャは、 選択されている食べ物の名前をアプリケーションの複数行エディット コントロールに追加し、 EndDialog関数を呼び出してダイアログ ボックスをクローズします。

コントロール識別子がIDCANCELならば、 ユーザーが[Cancel]ボタンをクリックしたことを示しています。この場合、 ダイアログ ボックス プロシージャは、 EndDialogを呼び出してダイアログ ボックスをクローズします。

[Square Meal]ダイアログ ボックスの作成

[Square Meal]ダイアログ ボックスのダイアログ ボックス プロシージャと補助関数を次に示します。

HWND hwndMain;
HWND hwndEdit;
char achTemp[256]; /* temporary buffer */

HBITMAP hbmBread;
HBITMAP hbmDairy;
HBITMAP hbmFruit;
HBITMAP hbmMeat;
HBITMAP hbmBreadMask;
HBITMAP hbmDairyMask;
HBITMAP hbmFruitMask;
HBITMAP hbmMeatMask;
/********************************************************
FUNCTION: FoodDlgProc
PURPOSE: Dialog procedure for Food dialog box.
*********************************************************/

BOOL CALLBACK FoodDlgProc(hwndDlg, msg, wParam, lParam)
HWND hwndDlg;
UINT msg;
WPARAM wParam;