关于列表框

列表框控件包含一个简单的列表,用户通常可从中选择一个或多个项。 与 列表视图 控件相比,列表框提供有限的灵活性。

列表框项可以由文本字符串、位图或两者表示。 如果列表框不够大,无法同时显示所有列表框项,则列表框提供滚动条。 用户滚动浏览列表框项,并根据需要应用或删除选择状态。 选择列表框项会更改其视觉外观,通常通过将文本和背景颜色更改为由相关操作系统指标指定的颜色。 当用户选择或取消选择某个项时,系统将通知消息发送到列表框的父窗口。

对于 ANSI 应用程序,系统使用 CP_ACP 代码页将列表框中的文本转换为 Unicode。 这可能会导致问题。 例如,Windows的非 Unicode 列表框中的重音罗马字符,日语版本将出现乱码。 若要解决此问题,可将应用程序编译为 Unicode 或使用所有者绘制的列表框。

本部分讨论以下主题:

创建列表框

在对话框中创建列表框的最简单方法是将其从工具箱拖到对话资源Microsoft Visual Studio。 若要动态创建列表框,或在对话框以外的窗口中创建列表框,请使用 CreateWindowEx 函数,指定 WC_LISTBOX 窗口类和相应的 列表框样式

列表框类型和样式

有两种类型的列表框:单选 (默认) 和多选。 在单选列表框中,用户一次只能选择一个项目。 在多选列表框中,用户可以一次选择多个项。 若要创建多选列表框,请指定 LBS_MULTIPLESELLBS_EXTENDEDSEL 样式。

列表框的外观和操作由 列表框样式 和窗口样式控制。 这些样式指示列表是否排序、排列在多个列中、由应用程序绘制等。 列表框的维度和样式通常在应用程序资源中包含的对话框模板中定义。

注意

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

列表框函数

DlgDirList 函数将列表框的内容替换为与指定条件集匹配的驱动器、目录和文件的名称。 DlgDirSelectEx 函数检索由 DlgDirList 初始化的列表框中的当前选择。 通过这些函数,用户可以从列表框中选择驱动器、目录或文件,而无需键入文件的位置和名称。

此外, GetListBoxInfo 函数返回指定列表框中每列的项目数。

来自列表框的通知消息

当在列表框中发生事件时,列表框会以 WM_COMMAND 消息的形式将通知代码发送到所有者窗口的对话框过程。 当用户选择、双击或取消列表框项时,将发送列表框通知代码;当列表框接收或失去键盘焦点时;当系统无法为列表框请求分配足够的内存时。 WM_COMMAND消息包含 wParam 参数的低序单词中的列表框标识符,以及高序单词中的通知代码。 lParam 参数包含控件窗口句柄。

处理这些消息不需要对话框过程;默认窗口过程处理它们。

应用程序应监视并处理以下列表框通知代码。

通知代码 描述
LBN_DBLCLK 用户双击列表框中的项。
LBN_ERRSPACE 列表框无法分配足够的内存来满足请求。
LBN_KILLFOCUS 列表框丢失键盘焦点。
LBN_SELCANCEL 用户取消列表框中项的选择。
LBN_SELCHANGE 列表框中的选择即将更改。
LBN_SETFOCUS 列表框接收键盘焦点。

消息到列表框

对话框过程可以将消息发送到列表框,以便添加、删除、检查和更改列表框项。 例如,对话框过程可以将 LB_ADDSTRING 消息发送到列表框以添加项,以及 一个LB_GETSEL 消息,以确定该项是否已选中。 其他消息设置和检索有关列表框的大小、外观和行为的信息。 例如, LB_SETHORIZONTALEXTENT 消息设置列表框的可滚动宽度。 对话框过程可以使用 SendMessageSendDlgItemMessage 函数将任何消息发送到列表框。

列表框项通常 由索引引用,该整数表示项在列表框中的位置。 列表框中第一项的索引为 0,第二项的索引为 1,依此等。

下表介绍了预定义列表框过程如何响应列表框消息。

消息 响应
LB_ADDFILE 将文件插入 到由 DlgDirList 函数填充的目录列表框中,并检索插入项的列表框索引。
LB_ADDSTRING 将字符串添加到列表框并返回其索引。
LB_DELETESTRING 从列表框中删除字符串,并返回列表中保留的字符串数。
LB_DIR 将文件名列表添加到列表框,并返回添加的姓氏的索引。
LB_FINDSTRING 返回列表框中以指定字符串开头的第一个字符串的索引。
LB_FINDSTRINGEXACT 返回与指定字符串相等的列表框中字符串的索引。
LB_GETANCHORINDEX 返回鼠标上次选择的项的索引。
LB_GETCARETINDEX 返回具有焦点矩形的项的索引。
LB_GETCOUNT 返回列表框中的项数。
LB_GETCURSEL 返回当前所选项的索引。
LB_GETHORIZONTALEXTENT 返回列表框的可滚动宽度(以像素为单位)。
LB_GETITEMDATA 返回与指定项关联的值。
LB_GETITEMHEIGHT 返回列表框中项的高度(以像素为单位)。
LB_GETITEMRECT 检索指定列表框项的客户端坐标。
LB_GETLOCALE 检索列表框的区域设置。 高阶单词包含国家/地区代码,低序单词包含语言标识符。
LB_GETSEL 返回列表框项的选择状态。
LB_GETSELCOUNT 返回多选列表框中选定的项数。
LB_GETSELITEMS 在多选列表框中创建所有选定项的索引数组,并返回所选项的总数。
LB_GETTEXT 检索与指定项和字符串长度关联的字符串。
LB_GETTEXTLEN 返回与指定项关联的字符串的长度(以字符为单位)。
LB_GETTOPINDEX 返回列表框中第一个可见项的索引。
LB_INITSTORAGE 为指定的项数及其关联的字符串分配内存。
LB_INSERTSTRING 在列表框中的指定索引处插入字符串。
LB_ITEMFROMPOINT 检索列表框中最接近指定点的项的从零开始的索引。
LB_RESETCONTENT 从列表框中删除所有项。
LB_SELECTSTRING 选择与指定前缀匹配的第一个字符串。
LB_SELITEMRANGE 选择列表框中的指定项目范围。
LB_SELITEMRANGEEX 如果区域中第一项的索引小于该区域中最后一项的索引,则选择指定的项范围。 如果第一项的索引大于最后一项,则取消区域中的选择。
LB_SETANCHORINDEX 设置鼠标最后选择指定项的项。
LB_SETCARETINDEX 将焦点矩形设置为指定的列表框项。
LB_SETCOLUMNWIDTH 设置列表框中所有列的宽度(以像素为单位)。
LB_SETCOUNT 设置列表框中的项目数。
LB_SETCURSEL 选择指定的列表框项。
LB_SETHORIZONTALEXTENT 设置列表框的可滚动宽度(以像素为单位)。
LB_SETITEMDATA 将值与列表框项相关联。
LB_SETITEMHEIGHT 设置列表框中项的高度(以像素为单位)。
LB_SETLOCALE 设置列表框的区域设置,并返回以前的区域设置标识符。
LB_SETSEL 在多选列表框中选择一个项目。
LB_SETTABSTOPS 将制表位设置为指定数组中指定的值。
LB_SETTOPINDEX 滚动列表框,以便指定的项位于可见区域顶部。

默认窗口消息处理

预定义列表框窗口类的窗口过程对列表框未处理的所有消息执行默认处理。 当列表框过程返回消息的 FALSE 时,预定义的窗口过程会检查消息并执行默认操作,如下表所示。

消息 默认操作
WM_CHAR 将所选内容移动到以用户键入的字符开头的第一个项目。 如果列表框具有 L BS_OWNERDRAW 样式,则不会发生任何操作。 在短间隔内键入的多个字符被视为组,并且选择以该系列字符开头的第一个项目。
WM_CREATE 创建空列表框。
WM_DESTROY 销毁列表框并释放它使用的任何资源。
将消息传递给对话框过程或父窗口进程。
WM_ENABLE 如果控件可见,则使矩形失效,以便字符串可以绘制为灰色。
WM_ERASEBKGND 清除列表框的背景。 如果列表框具有 L BS_OWNERDRAW 样式,则不会擦除背景。
WM_GETDLGCODE 返回DLGC_WANTARROWS |DLGC_WANTCHARS,指示默认列表框过程处理箭头键和 WM_CHAR 消息。
WM_GETFONT 返回列表框的当前字体的句柄。
WM_HSCROLL 水平滚动列表框。
WM_KEYDOWN 处理用于滚动的虚拟密钥。 虚拟键是要将插入点移动到的项的索引。 所选内容不会更改。
WM_KILLFOCUS 关闭插入点并销毁它。 将 LBN_KILLFOCUS 通知代码发送到列表框的所有者。
WM_LBUTTONDBLCLK 跟踪列表框工作区中的鼠标。 这样,如果用户在列表框工作区外释放鼠标按钮,则取消选择。
WM_LBUTTONDOWN 跟踪列表框工作区中的鼠标。 这样,如果用户在列表框工作区外释放鼠标按钮,则取消选择。
WM_LBUTTONUP 跟踪列表框工作区中的鼠标。 这样,如果用户在列表框工作区外释放鼠标按钮,则取消选择。
WM_MOUSEMOVE 跟踪列表框工作区中的鼠标。 这样,如果用户在列表框工作区外释放鼠标按钮,则取消选择。
WM_PAINT 使用列表框句柄对设备上下文执行子类化绘制操作, (DC) 。
WM_SETFOCUS 打开插入点并将 LBN_SETFOCUS 通知代码发送到列表框的所有者。
WM_SETFONT 设置列表框的新字体。
WM_SETREDRAW 根据 wParam 的值设置或清除重绘标志。
WM_SIZE 将列表框的大小调整为整型项数。
WM_VSCROLL 垂直滚动列表框。

预定义列表框过程将所有其他消息传递到 DefWindowProc 进行默认处理。

Owner-Drawn列表框

应用程序可以创建 所有者绘制 列表框,以负责绘制列表项。 所有者绘制列表框的父窗口或对话框 (其 所有者) 在需要绘制列表框的一部分时接收 WM_DRAWITEM 消息。 所有者绘制的列表框可以列出除文本字符串以外的其他信息。

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

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

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

如果所有者绘制的列表框中显示的信息包括文本,则应用程序可以通过指定 LBS_HASSTRINGS 样式来跟踪每个列表项的文本。 带有 LBS_SORT 样式的列表框根据此文本进行排序。 如果列表框已排序,但不是 LBS_HASSTRINGS 样式,则所有者必须处理 WM_COMPAREITEM 消息。

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

有关所有者绘制的列表框的示例,请参阅 “如何创建Owner-Drawn列表框”。

拖动列表框

拖动列表框是一种特殊类型的列表框,允许用户将项目从一个位置拖动到另一个位置。 应用程序可以使用拖动列表框显示特定序列中的字符串,并使用户能够通过将项拖动到位置来更改序列。

创建拖动列表框

拖动列表框具有相同的窗口样式,并处理与标准列表框相同的消息。 若要创建拖动列表框,请先创建标准列表框,然后调用 MakeDragList 函数。 若要将对话框中的列表框转换为拖动列表框,可以在处理WM_INITDIALOG消息时调用 MakeDragList

拖动列表框消息

拖动列表框通过向其发送拖动列表消息来通知拖动事件的父窗口。 父窗口必须处理拖动列表消息。

调用 MakeDragList 函数时,拖动列表框会注册此消息。 若要检索拖动列表消息 (数值) 的消息标识符,请调用 RegisterWindowMessage 函数并指定 DRAGLISTMSGSTRING 值。

拖动列表消息的 wParam 参数是拖动列表框的控制标识符。 lParam 参数是 DRAGLISTINFO 结构的地址,其中包含拖动事件和其他信息的通知代码。 消息的返回值取决于通知。

拖动列表框通知代码

拖动列表通知代码(由拖动列表消息随附的 DRAGLISTINFO 结构的 uNotification 成员标识)可以DL_BEGINDRAGDL_DRAGGINGDL_CANCELDRAGDL_DROPPED

当光标位于列表项上并且用户单击鼠标左键时,将发送 DL_BEGINDRAG 通知代码。 父窗口可以返回 TRUE 以开始拖动操作或 FALSE 以禁止拖动。 这样,父窗口就可以为某些列表项启用拖动,并为其他列表项禁用它。 可以使用 LBItemFromPt 函数确定位于指定位置的列表项。

如果拖动有效, 则每当 移动鼠标时,DL_DRAGGING通知代码将发送,或者在未移动鼠标时定期发送通知代码。 父窗口应首先使用 LBItemFromPt 确定光标下的列表项,然后使用 DrawInsert 函数绘制插入图标。 通过为 LBItemFromPtbAutoScroll 参数指定 TRUE,如果光标位于其工作区上方或下方,则可能会导致列表框滚动一行。 为此通知返回的值指定拖动列表框应设置的鼠标光标的类型。

如果用户通过单击鼠标右键或按 ESC 键取消拖动操作,则会发送 DL_CANCELDRAG 通知代码。 如果用户通过释放鼠标左键完成拖动操作,则发送 DL_DROPPED 通知代码,即使光标不在列表项上也是如此。 拖动列表框在发送任一通知之前释放鼠标捕获。 忽略这两个通知的返回值。 拖动列表