关于组合框

组合框合并编辑框或静态文本和列表。

本主题包含以下各节:

组合框类型和样式

组合框由列表和选择字段组成。 该列表显示用户可以选择的选项,并且选择字段显示当前所选内容。 如果选择字段是编辑控件,用户可以输入列表中不可用的信息;否则,用户只能选择列表中的项。

通用控件库包括组合框的三种主要样式,如下表所示。

组合框类型 样式常量 说明
简单 CBS_SIMPLE 随时显示列表,并在编辑控件中显示所选项。
Drop-down CBS_DROPDOWN 单击图标时显示列表,并在编辑控件中显示所选项。
下拉列表 (下拉列表) CBS_DROPDOWNLIST 单击图标时显示列表,并在静态控件中显示所选项。

 

以下屏幕截图分别显示三种类型的组合框,因为它们可能显示在 Windows Vista 中。 在第一个屏幕截图中,用户已在简单组合框中选择了一个项目。 用户还可以在此控件的编辑框中键入新值。 列表已在Microsoft Visual Studio资源编辑器中调整大小,并且仅足够大,足以容纳两个项目。

screen shot showing an item selected in a simple combo box

第二个屏幕截图中,用户在下拉列表组合框的编辑控件中键入了新文本。 用户还可以选择现有项。 列表框展开以容纳尽可能多的项。

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

在第三个屏幕截图中,用户已打开下拉列表组合框。 列表框展开以容纳尽可能多的项。 用户无法输入新文本。

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

还有一些组合框样式用于定义特定属性。 组合框样式定义组合框的特定属性。 可以组合样式;但是,某些样式仅适用于某些组合框类型。 有关组合框样式表,请参阅 组合框样式

注意

若要对组合框使用视觉样式,应用程序必须包含清单,并且必须在程序开头调用 InitCommonControls 。 有关视觉样式的信息,请参阅 视觉样式。 有关清单的信息,请参阅 “启用视觉样式”。

 

组合框列表

列表是组合框的一部分,显示用户可以选择的项目。 通常,应用程序在创建组合框时初始化列表的内容。 用户选择的任何列表项都是 当前选择项。 无法选择多个项。 在简单和下拉列表组合框中,用户可以在选择字段中键入,而不是选择列表项。 在这些情况下,没有当前选择,应用程序有责任将项目添加到列表中,并将其设置为当前选择(如果适用)。

本节讨论以下主题:

当前所选内容

当前选择是用户选择的列表项;所选文本显示在组合框的选择字段中。 但是,对于简单的组合框或下拉组合框,当前选择只是组合框中可能的用户输入的一种形式。 用户还可以在选择字段中键入文本。

当前选择由所选列表项的从零开始的索引标识。 应用程序可以随时设置和检索它。 当用户更改组合框的当前选择时,父窗口或对话框过程会收到通知。 应用程序更改选择时,不会通知父窗口或对话框。

创建组合框时,没有当前选择。 如果用户编辑了选择字段的内容,则对于简单或下拉组合框也是如此。 若要设置当前选择,应用程序会将 CB_SETCURSEL 消息发送到组合框。 应用程序还可以使用 CB_SELECTSTRING 消息将当前选定内容设置为字符串以指定字符串开头的列表项。 若要确定当前选择,应用程序会将 CB_GETCURSEL 消息发送到组合框。 如果没有当前选择,此消息将返回CB_ERR。

当用户更改组合框中的当前选定内容时,父窗口或对话框过程将收到一条WM_COMMAND消息,其中包含 wParam 参数的高序单词中的CBN_SELCHANGE通知代码。 使用 CB_SETCURSEL 消息设置当前选择时,不会发送此通知代码。

下拉列表关闭时,下拉列表框或下拉列表框会将 CBN_CLOSEUP 通知代码发送到父窗口或对话框过程。 如果用户更改了当前选择,则组合框还会在下拉列表关闭时发送 CBN_SELCHANGE 通知代码。 若要每次用户选择列表项时执行特定进程,可以处理CBN_SELCHANGE或CBN_CLOSEUP通知代码。 通常,在处理当前所选内容的更改之前,需要等待CBN_CLOSEUP通知代码。 如果需要大量的处理,这尤其重要。

应用程序还可以处理 CBN_SELENDOKCBN_SELENDCANCEL 通知代码。 当用户选择列表项或选择某个项,然后关闭列表时,系统会发送CBN_SELENDOK。 这表示用户已完成,并且应处理所选内容。 当用户选择某个项时发送CBN_SELENDCANCEL,但随后选择另一个控件,在下拉列表处于打开状态时按 ESC,或关闭对话框。 这表示应忽略用户的选择。 CBN_SELENDOK在每个 CBN_SELCHANGE 消息之前发送。

在简单的组合框中,当用户双击列表项时,系统会发送 CBN_DBLCLK 通知代码。 在下拉列表组合框或下拉列表中,单击一下即可隐藏列表,因此无法双击某个项。

某些通知和消息仅适用于包含下拉列表的组合框。 当下拉列表处于打开或关闭状态时,组合框的父窗口以 WM_COMMAND 消息的形式接收通知。 如果打开列表, 则 wParam 的高阶单词 CBN_DROPDOWN。 如果列表正在关闭,则 CBN_CLOSEUP

应用程序可以使用 CB_SHOWDROPDOWN 消息打开下拉列表框或下拉列表框的列表。 它可以使用 CB_GETDROPPEDSTATE 消息确定列表是否打开,并且可以使用 CB_GETDROPPEDCONTROLRECT 消息确定下拉列表的坐标。 应用程序还可以使用 CB_SETDROPPEDWIDTH 消息来增加下拉列表的宽度。

列出内容

当应用程序创建组合框时,通常会通过将一个或多个项添加到列表来初始化组合框。 稍后,应用程序可以添加或删除列表项、重新初始化列表或从中检索项信息。

应用程序通过将 CB_ADDSTRING 消息发送到组合框,将列表项添加到组合框中。 指定的项将添加到列表的末尾,或者,在排序的组合框中,根据项的字符串正确排序位置。 在未排序的组合框中,应用程序可以使用 CB_INSERTSTRING 消息将项插入到特定位置。 添加后,列表项由其位置标识。

通过使用 CB_FINDSTRINGCB_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 样式,文本可以继续超出所选字段的大小。 无论控件是否具有CBS_AUTOHSCROLL样式,应用程序都可以使用CB_LIMITTEXT消息来限制用户可以键入到所选字段的文本量。

当用户编辑所选字段的内容时,父窗口或对话框过程会收到通知消息。 首先发送 CBN_EDITUPDATE 通知代码,指示已编辑所选字段中的文本。 显示更改的文本后,系统会发送 CBN_EDITCHANGE。 当所选字段内容更改为选定列表项的结果时,不会发送这些消息。

Owner-Drawn组合框

应用程序可以创建所有者绘制组合框,以负责绘制列表项。 所有者绘制组合框的父窗口 (其所有者) 在需要绘制组合框的一部分时接收 WM_DRAWITEM 消息。 所有者绘制组合框可以列出除文本字符串以外的其他信息。 所有者绘制组合框可以是任何类型的。 但是,简单或下拉组合框中的编辑控件只能显示文本,而所有者在下拉列表框中绘制选择字段。

所有者绘制组合框的所有者必须处理 WM_DRAWITEM 消息。 每当必须重绘组合框的一部分时,都会发送此消息。 所有者可能需要处理其他消息,具体取决于组合框指定的样式。

应用程序可以通过指定 CBS_OWNERDRAWFIXEDCBS_OWNERDRAWVARIABLE 样式来创建所有者绘制的组合框。 如果组合框中的所有列表项的高度相同,如字符串或图标,则应用程序可以使用 CBS_OWNERDRAWFIXED 样式。 如果列表项的高度不同,如不同大小的位图,则应用程序可以使用 CBS_OWNERDRAWVARIABLE 样式。

所有者绘制组合框的所有者可以处理 WM_MEASUREITEM 消息,以指定组合框中列表项的尺寸。 如果应用程序使用 CBS_OWNERDRAWFIXED 样式创建组合框,则系统仅发送 一次WM_MEASUREITEM 消息。 所有者指定的维度用于所有列表项。 如果使用 CBS_OWNERDRAWVARIABLE 样式,系统会为添加到组合框的每个列表项发送 WM_MEASUREITEM 消息。 所有者可以使用 CB_GETITEMHEIGHTCB_SETITEMHEIGHT 消息,随时确定或设置列表项的高度。

如果所有者绘制组合框中显示的信息包括文本,则应用程序可以通过指定 CBS_HASSTRINGS 样式来跟踪每个列表项的文本。 具有 CBS_SORT 样式的组合框基于此文本进行排序。 如果组合框已排序而不是 CBS_HASSTRINGS 样式,则所有者必须处理 WM_COMPAREITEM 消息。

在所有者绘制的组合框中,所有者必须跟踪包含除文本以外的信息的列表项。 执行此操作的一种便捷方法是将句柄另存为项数据。 若要释放与组合框中的项目关联的数据对象,所有者可以处理 WM_DELETEITEM 消息。

子类组合框

子类化是一个过程,允许应用程序截获和处理发送到窗口或发布到窗口的消息。 通过使用子类分析,应用程序可以替换其自身对某些消息的处理,同时将大多数消息处理留给类定义的窗口过程。

当操作系统创建窗口时,它会在包含指向窗口过程的指针的内部数据结构中保存有关它的信息。 若要对窗口进行子类,应用程序调用 SetClassLong 函数,将指向该过程的指针替换为指向应用程序定义的子类过程的指针。 此后,向窗口发送所有消息都会发送到子类过程。 然后,此过程使用 CallWindowProc 函数将未处理的消息传递给原始窗口过程。 有关 COMBOBOX 类窗口过程执行的消息处理的说明,请参阅 默认组合框行为

组合框在对话框外部时,除非应用程序使用子类过程,否则应用程序无法处理 TAB、ENTER 和 ESC 键。 当简单组合框或下拉组合框收到输入焦点时,它会立即将焦点设置为其子编辑控件。 因此,应用程序必须对编辑控件进行子类,以截获简单组合框或下拉组合框的键盘输入。 有关此示例,请参阅 子类化组合框

如果子类过程处理 WM_PAINT 消息,则必须使用 BeginPaint 函数来准备绘制。 在调用 EndPaint 函数之前,它将设备上下文 (DC) 句柄作为窗口过程的 wParam 参数传递。 如果首先调用 EndPaint ,则类窗口过程不会进行绘制,因为 EndPaint 会验证整个窗口。

与子类分析相关的技术是超类。 超级类类似于任何其他类,但其窗口过程不调用 DefWindowProc 来处理未处理的消息。 而是将未处理的消息传递给父窗口类的窗口过程。 遵循 Window Procedures 中的准则,以避免子类和超级类化可能出现的问题。