列表框是将一批文本字符串显示在一个具有滚动功能的方框中的控件。通过发送消息到列表框的窗口过程,程序可以添加或删除列表中的字符串。当列表框中的一个项目被选中时,列表框控件便发送 WM_COMMAND消息到其父窗口。然后父窗口确定哪个项目被选中。
本节必须掌握的知识点:
列表框类控件
第54练:列表框控件
第55练:列表框控件—head程序
8.5.1 列表框类控件
■列表框控件分类
列表框可以是单选的或多选的。后者允许用户从列表框中选择一个以上的项目。当一个列表框获得输入焦点时,它会在列表框的一个项目周围显示虚线框。这种光标并不表示列表框中的选中项。被选中的项目通过高亮显示来表示。
●在单选列表框中,用户可以按动空格键选择光标所在的项目。方向键可以同时移动光 标和当前的选择,并可以滚动列表框中的内容。上下翻页键也可通过移动光标来滚动列表框,但不会移动选择的项目。按下一个字母键可移动光标和当前选择到以那个字母开头的第一项(或下一项)。通过在某一项上单击或双击鼠标也可以选中该项。
●在多选列表框中,空格键用于切换光标所在项目的选择状态。(如果该项目已经被选定, 它的选定状态会被取消。)方向键取消所有以前选定的项目,并移动光标和选中项,就像在单选列表框中一样。然而,Ctrl键加方向键可以移动光标,但不移动选中项。Shift键加方向键可以扩展选中项。
单击或双击多选列表框中的一个项目,会取消所有先前选定的项目,只选择被单击的项目。然而,在单击一个项目的同时按下Shift键会切换该项目的选择状态而不改变任何其他项目的选择状态。
■列表框控件的重要信息和功能
●创建列表框控件:可以使用 CreateWindowEx 或 CreateWindow 函数来创建列表框控件。需要指定控件类名为 "LISTBOX",并设置相应的样式和属性。
●添加项:使用 LB_ADDSTRING 消息或 ListBox_AddString 函数向列表框中添加文本项。每个项都具有唯一的索引,可以使用该索引进行引用和操作。
●删除项:使用 LB_DELETESTRING 消息或 ListBox_DeleteString 函数从列表框中删除指定索引的项。
●获取选中项:使用 LB_GETCURSEL 消息或 ListBox_GetCurSel 函数获取当前选中项的索引。可以进一步使用 LB_GETTEXT 消息或 ListBox_GetText 函数获取选中项的文本内容。
●选择项:使用 LB_SETCURSEL 消息或 ListBox_SetCurSel 函数设置列表框中指定索引的项为选中状态。
●多选功能:通过设置列表框控件的样式为 LBS_MULTIPLESEL,可以启用多选功能。用户可以按住 Ctrl 键或 Shift 键进行多项选择。
●滚动条:当列表框中的项超过可见区域时,会自动出现垂直滚动条,以方便导航。
●通知消息:列表框控件可以发送一系列的通知消息,用于响应用户的操作或状态变化。例如,LBN_SELCHANGE 消息在选中项发生变化时发送。
●自定义绘制:可以通过处理 WM_DRAWITEM 消息来自定义绘制列表框中的项,以改变其外观和样式。
●其他操作:还有许多其他的列表框操作和功能,如获取项的数量、清空列表框、滚动列表框等。
●键盘操作
| 键盘操作 |
单选列表框 |
多选列表框 |
| 空格键 |
选择光标所在项 |
切换选中状态 |
| 方向键 |
移动光标和当前的选择 |
取消以前所选,并移动光标和选中项 |
| 翻页键 |
移动光标,但不移动选择项 |
|
| 字母键 |
移动和选择以该字母开头的第一项 |
|
| Ctrl+方向 |
移动光标,但不移动选中项 |
|
| Shift+方向 |
扩展选中项 |
|
■列表框的样式
列表框控件(List Box Control)提供了一些样式选项,可以用于自定义列表框的外观和行为。以下是一些常用的列表框样式:
●LBS_STANDARD:标准列表框样式,默认样式,显示垂直滚动条并支持单选。
●LBS_SORT:排序样式,列表框中的项按字母顺序排序。
●LBS_MULTIPLESEL:多选样式,允许用户选择列表框中的多个项。用户可以按住 Ctrl 键或 Shift 键进行多项选择。
●LBS_EXTENDEDSEL:扩展多选样式,类似于 LBS_MULTIPLESEL,但支持连续选择。用户可以按住鼠标左键拖动以选择多个连续项。
●LBS_OWNERDRAWFIXED:固定尺寸的自绘样式,允许自定义绘制列表框中的项。
●LBS_NOINTEGRALHEIGHT:禁用自动调整高度样式,列表框的高度将根据项的数量进行调整。
●LBS_DISABLENOSCROLL:禁用无项时的滚动条样式,即使列表框中没有项,也显示垂直滚动条。
●LBS_NODATA:无数据样式,仅用于通知列表框控件不包含任何数据。
●这些样式可以通过在创建列表框控件时使用 CreateWindowEx 或 CreateWindow 函数的 dwStyle 参数来设置。例如:
HWND hListBox = CreateWindowEx(
0, // 扩展窗口样式
L"LISTBOX", // 窗口类名
NULL, // 窗口标题
WS_VISIBLE | WS_CHILD | LBS_STANDARD, // 窗口样式
x, y, width, height, // 窗口位置和尺寸
hWndParent, // 父窗口句柄
(HMENU)IDC_LISTBOX, // 控件标识符
hInstance, // 应用程序实例句柄
NULL // 创建参数
);
在上述示例中,我们创建了一个具有标准样式的列表框控件,并设置了一些常用的样式,如可见、子窗口。可以根据需求自由组合和设置其他样式。
●除了创建时设置样式,还可以使用 SetWindowLongPtr 或 SetWindowLongPtr 函数来动态修改列表框控件的样式。例如:
DWORD dwStyle = GetWindowLongPtr(hListBox, GWL_STYLE);
dwStyle |= LBS_SORT; // 设置排序样式
SetWindowLongPtr(hListBox, GWL_STYLE, dwStyle);
在上述示例中,我们首先获取列表框控件的当前样式,然后通过按位或运算符将 LBS_SORT 样式添加到样式中,最后使用 SetWindowLongPtr 函数设置新的样式。
这些是一些常见的列表框样式,你可以根据具体的需求选择适合的样式来自定义列表框的外观和行为。
■向列表框中添加字符串
要向列表框中添加字符串,你可以使用 LB_ADDSTRING 消息或 ListBox_AddString 函数。下面是一个示例:
●使用 LB_ADDSTRING 消息:
HWND hListBox = GetDlgItem(hWnd, IDC_LISTBOX); // 获取列表框控件句柄
SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)L"Item 1"); // 添加字符串项
SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)L"Item 2"); // 添加字符串项
●使用 ListBox_AddString 函数:
HWND hListBox = GetDlgItem(hWnd, IDC_LISTBOX); // 获取列表框控件句柄
ListBox_AddString(hListBox, L"Item 1"); // 添加字符串项
ListBox_AddString(hListBox, L"Item 2"); // 添加字符串项
在上述示例中,我们首先获取列表框控件的句柄 hListBox,然后使用 LB_ADDSTRING 消息或 ListBox_AddString 函数将字符串项添加到列表框中。每个字符串项都是一个以 null 终止的 Unicode 字符串,使用 LPARAM 类型进行传递。
你可以根据需要多次调用 LB_ADDSTRING 消息或 ListBox_AddString 函数来添加多个字符串项。列表框将按照添加的顺序显示这些项。
请确保在添加字符串之前,列表框已经被创建并且有效。你可以使用 GetDlgItem 函数根据控件标识符获取列表框的句柄。
注意:在使用 LB_ADDSTRING 消息或 ListBox_AddString 函数添加字符串项之前,你需要确保列表框控件已经创建,且在窗口中可见。
■项目的选择和提取
要选择列表框中的项目并提取选中的项目,你可以使用 LB_GETCURSEL 消息或 ListBox_GetCurSel 函数来获取当前选中项目的索引。然后,使用 LB_GETTEXT 消息或 ListBox_GetText 函数来获取选中项目的文本内容。
下面是一个示例:
●使用 LB_GETCURSEL 消息和 LB_GETTEXT 消息:
HWND hListBox = GetDlgItem(hWnd, IDC_LISTBOX); // 获取列表框控件句柄
// 获取当前选中项目的索引
int selectedIndex = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
if (selectedIndex != LB_ERR) {
// 获取选中项目的文本长度
int textLength = SendMessage(hListBox, LB_GETTEXTLEN, selectedIndex, 0);
if (textLength != LB_ERR) {
// 分配内存来存储选中项目的文本
wchar_t* buffer = new wchar_t[textLength + 1];
// 获取选中项目的文本内容
SendMessage(hListBox, LB_GETTEXT, selectedIndex, (LPARAM)buffer);
// 在这里可以使用选中项目的文本内容
delete[] buffer; // 释放内存
}
}
●使用 ListBox_GetCurSel 函数和 ListBox_GetText 函数:
HWND hListBox = GetDlgItem(hWnd, IDC_LISTBOX); // 获取列表框控件句柄
// 获取当前选中项目的索引
int selectedIndex = ListBox_GetCurSel(hListBox);
if (selectedIndex != LB_ERR) {
// 获取选中项目的文本长度
int textLength = ListBox_GetTextLen(hListBox, selectedIndex);
if (textLength != LB_ERR) {
// 分配内存来存储选中项目的文本
wchar_t* buffer = new wchar_t[textLength + 1];
// 获取选中项目的文本内容
ListBox_GetText(hListBox, selectedIndex, buffer);
// 在这里可以使用选中项目的文本内容
delete[] buffer; // 释放内存
}
}
在上述示例中,我们首先获取列表框控件的句柄 hListBox。然后,使用 LB_GETCURSEL 消息或 ListBox_GetCurSel 函数获取当前选中项目的索引。如果索引不是 LB_ERR,表示有项目被选中。
接下来,我们使用 LB_GETTEXTLEN 消息或 ListBox_GetTextLen 函数获取选中项目的文本长度。如果长度不是 LB_ERR,表示获取长度成功。
然后,我们分配足够的内存来存储选中项目的文本,使用 LB_GETTEXT 消息或 ListBox_GetText 函数获取选中项目的文本内容,并将其存储在我们分配的缓冲区中。
在获取到选中项目的文本内容后,你可以在相应的位置使用该文本进行处理。最后,不要忘记释放分配的内存,以避免内存泄漏。
■接收来自列表框的消息
要接收来自列表框的消息,你需要在消息处理函数或窗口过程中处理列表框相关的消息。
当用户用鼠标单击一个列表框时,这个列表框将获得输入焦点。父窗口可以通过下面的调用把输入焦点给一个列表框控件:
SetFocus ( hwndList );
当一个列表框具有输入焦点时,光标移动键、字符键和空格键也可用于从列表框中选择项目。
—个列表框控件会发送WM COMMAND信息到其父窗口。相应的wParam和IParam 变量的含义和在按钮控件、编辑控件中是一样的:
LOWORD (wParam) 子窗口 ID
HIWORD (wParam) 通知码
IParam 子窗口句柄
通知码和它们的值如下:
LBN_ERRSPACE -2 //表明该列表框控件己经用尽了它的空间
LBN_SELCHANGE 1 //表明当前的选择发生了变化
LBN_DBLCLK 2 //代码表明列表框中的某个项目己被鼠标双击
LBN_SELCANCEL 3 //通知应用程序用户已取消列表框中的选择
LBN_SETFOCUS 4 //通知应用程序列表框已收到键盘焦点
LBN_KILLFOCUS 5 //通知应用程序列表框已失去键盘焦点
只有在列表框窗口样式包含了 LBS_NOTIFY时,列表框控件才会向父窗口发送 LBN_SELCHANGE 和 LBN_DBLCLK。
LBN_ERRSPACE代码表明,该列表框控件己经用尽了它的空间。
LBN_SELCHANGE 代码表明当前的选择发生了变化:这些消息可能出现在当用户在列表框中移动高亮显示的选中项时,或是通过空格键切换选择状态时,又或者是用鼠标单击一个项目时。
LBN_DBLCLK代码表明列表框中的某个项目己被鼠标双击。(通知码LBN_SELCHANGE 和LBN_DBLCLK的值表明了鼠标单击的次数。)
根据你的应用程序,你可能想要使用LBN_SELCHANGE或LBN_DBLCLK,或同时使用这两者。程序将收到许多LBN_SELCHANGE消息,但只有当用户用鼠标双击时 LBN_DBLCLK才会出现。如果程序使用了双击,则需要提供一个键盘接口,以提供 LBN_DBLCLK的等效功能。
以下是一些常见的列表框消息及其处理方式:
●WM_COMMAND:列表框的选择变化会触发 WM_COMMAND 消息,其中的 wParam 参数指示了列表框的控件标识符,而 lParam 参数指示了列表框控件的句柄。可以使用 HIWORD(wParam) 来检查列表框事件类型。
case WM_COMMAND:
{
int controlId = LOWORD(wParam); // 获取控件标识符
if (controlId == IDC_LISTBOX) // 检查列表框控件标识符
{
int eventType = HIWORD(wParam); // 获取事件类型
if (eventType == LBN_SELCHANGE) // 选择变化事件
{
// 处理列表框选择变化的逻辑
// 可以使用 SendMessage 或 ListBox_GetCurSel 等函数
获取选中项的索引或文本
}
}
}
break;
●WM_NOTIFY:通过设置列表框的扩展样式为 LBS_NOTIFY,可以接收到更详细的通知消息。当列表框中的事件发生时,将会发送 WM_NOTIFY 消息,其中的 NMHDR 结构中的 code 成员表示事件类型。
case WM_NOTIFY:
{
NMHDR* nmhdr = (NMHDR*)lParam;
if (nmhdr->code == LBN_SELCHANGE) // 选择变化事件
{
// 处理列表框选择变化的逻辑
// 可以使用 SendMessage 或 ListBox_GetCurSel 等函数
获取选中项的索引或文本
}
}
break;
在上述示例中,我们检查了列表框相关消息中的事件类型,例如 LBN_SELCHANGE 表示选择变化事件。在事件处理逻辑中,你可以使用适当的函数(如 SendMessage 或 ListBox_GetCurSel)来获取选中项的索引或文本,并进行相应的处理。
需要注意的是,列表框控件是单列的,适用于显示简单的文本项。如果需要更复杂的布局或自定义内容,可以考虑使用组合框控件(Combo Box Control)或其他更高级的控件。
8.5.2 第54练:列表框控件
/*------------------------------------------------------------------
054 WIN32 API 每日一练
第54个例子ENVIRON.C:列表框类控件——显示环境变量
CreateWindow创建列表框控件
FillListBox函数对环境变量内存块进行解析
GetEnvironmentStrings 函数
GetEnvironmentVariable函数
(c) www.bcdaren.com, 2020
----------------------------------------------------------------*/
#include <windows.h>
#define ID_LIST 1
#define ID_TEXT 2
LRESULT CALLBACK

1164

被折叠的 条评论
为什么被折叠?



