对于 Listview 示例,没有什么比 Classic Sample 更清晰的了!
与此同时,Google 翻译以及 Unicode + 对 @Alejadro 的 Listview 的德语链接的救援进行了微小的修改 - 由于该页面不包含适当的 meta tag,因此搜索结果中没有提供直接翻译.为简洁起见剪了一点:
样式的后续变化
创建后可以更改 ListView 的样式。为此,使用了 GetWindowLong 和 SetWindowLong 函数。关于遮罩可以定义不同的样式。
面具..................................面具样式:
LVS_TYPEMASK.......LVS_ICON、LVS_LIST、LVS_REPORT 和 LVS_SMALLICON
LVS_ALIGNMASK.............LVS_ALIGNLEFT 和 LVS_ALIGNTOP
LVS_TYPESTYLEMASK...LVS_ALIGNLEFT 和 LVS_ALIGNTOP,还有 VS_NOCOLUMNHEADER 和 LVS_NOSORTHEADER
对于下面的序列,dwView包含要使用的样式,如LVS_REPORT or LVS_ICON。
DWORD dwStyle = GetWindowLong(hwndLV, GWL_STYLE); // get current style
if ((dwStyle & LVS_TYPEMASK)! = dwView) // only on change
SetWindowLong(hwndLV, GWL_STYLE, (dwStyle & ~ LVS_TYPEMASK) | dwView); }
ListView控件的控制
生成列表
使用 CreateWindow 函数创建一个列表视图。窗口类使用常量WC_LISTVIEW。为此,必须包含公共控制头文件。
#include "commctrl.h"
InitCommonControls();
hwndList = CreateWindow(WC_LISTVIEW, "",
WS_VISIBLE | WS_BORDER | WS_CHILD | LVS_REPORT | LVS_EDITLABELS,
10, 10, 300, 100,
hWnd, (HMENU) ID_LIST, hInst, 0);
在对话框中,它只是在资源中定义。
如果有未解析的外部,您应该检查是否包含通用控件的库 (comctl32.lib)。
ListView 的列
在REPORT 中插入内容之前,必须先定义列。列由结构LVCOLUMN 描述。以下例程创建一个列。
int CreateColumn(HWND hwndLV, int iCol, char * text, intwidth)
{
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = iWidth;
lvc.pszText = text;
lvc.iSubItem = iCol;
return ListView_InsertColumn(hwndLV, iCol, & lvc);
}
可以通过向 ListView 发送消息或调用最终执行 SendMessage 的宏来修改列。
Message Macro call Function
LVM_INSERTCOLUMN ListView_InsertColumn(HWND, int, LVCOLUMN * ) Insert column
LVM_DELETECOLUMN ListView_DeleteColumn(HWND, int) Delete column
LVM_GETCOLUMN ListView_GetColumn(HWND, int, LVCOLUMN * ) Get properties of the column
LVM_SETCOLUMN ListView_SetColumn(HWND, int, LVCOLUMN * ) Change properties of the column
LVM_GETCOLUMNWIDTH ListView_GetColumnWidth(HWND, int) Determine column width
LVM_SETCOLUMNWIDTH ListView_SetColumnWidth(HWND, int, int) Set column width
插入一行
ListView 的一个元素由LVITEMW 结构描述(见下文)。每个元素都可以表示为ICON、SMALLICON、LIST 元素或REPORT 行的左列。
int CreateItem(HWND hwndList, wchar_t * text)
{
LVITEMW lvi = {0};
lvi.mask = LVIF_TEXT;
lvi.pszText = text;
return ListView_InsertItem(hwndList, & lvi);
}
掩码字段确定LVITEMW 结构的哪些元素真正被使用。由于保持指向保存对象背后数据的内存对象的指针通常是有意义的,因此 lParam 字段很有用。为了使用它,LVIF_TEXT | LVIF_PARAM 必须设置为掩码。
掩码的常量和启用它们的字段:
LVIF_IMAGE iImage
LVIF_INDENT 缩进
LVIF_PARAM lParam
LVIF_STATE 状态
LVIF_TEXT pszText
报告的其他列
元素本身总是留在报表视图中并且是可选择的。要填充更多列,需要在项目中添加一个文本。
int Create2ColItem(HWND hwndList, wchar_t * Text1, wchar_t * Text2)
{
LVITEMW lvi = {0};
int Ret;
// Initialize LVITEMW members that are common to all items.
lvi.mask = LVIF_TEXT;
lvi.pszText = Text1;
Ret = ListView_InsertItem(hwndList, & lvi);
if (Ret >= 0)
{
ListView_SetItemText(hwndList, Ret, 1, Text2);
}
return Ret;
}
上面的Create2ColItem 最好通过以下语句来证明:
LVHwnd = Your_Create_LV_Routine();
if (LVHwnd)
{
CreateColumn(LVHwnd, 0, ptrColHeaderString1, iColSize1);
CreateColumn(LVHwnd, 1, ptrColHeaderString2, iColSize2);
Create2ColItem(LVHwnd, ptrItemText1, ptrItemText2);
}
LVITEMW结构
结构LVITEMW(在CommCtrl.h 中)描述了ListView 的一个元素。此处简要介绍了最重要的元素。先定义:
typedef struct tagLVITEMW
{
UINT mask;
int iItem;
int iSubItem;
UINT state;
UINT stateMask;
LPWSTR pszText;
int cchTextMax;
int iImage;
LPARAM lParam;
#if (_WIN32_IE >= 0x0300) //historical note for IE3 users!
int iIndent;
#endif
#if (NTDDI_VERSION >= NTDDI_WINXP)
int iGroupId;
UINT cColumns; // tile view columns
PUINT puColumns;
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
int* piColFmt;
int iGroup; // readonly. only valid for owner data.
#endif
} LVITEMW, *LPLVITEMW;
LVM_GETITEMW 和 LVM_SETITEMW 消息更改元素的属性。作为参数,你会得到一个指向 ListView 的 HWND 旁边的 LVITEMW 结构的指针,必须提前填写。
结构元素详解:
面具:
指定使用哪些元素。以下标志的组合是可能的:
LVIF_IMAGE iImage
LVIF_INDENT 缩进
LVIF_PARAM lParam
LVIF_STATE 状态
LVIF_TEXT pszText
iItem
结构相关项目的索引(从 0 开始)。
iSubItem
与结构相关的子项的索引(从 1 开始)。如果结构引用一个项目而不是子项目,则为 0。
pszText
指向一个以空字符结尾的字符串。如果值为LPWSTR_TEXTCALLBACK,则为回调项。如果这种情况发生变化,pszText 必须设置为LPSTR_TEXTCALLBACK,并且 ListView 由LVM_SETITEMW 或LVM_SETITEMTEXT 通知。
如果 ListView 的样式为 LVS_SORTASCENDING 或 LVS_SORTDESCENDING,则 pszText 不得设置为 LPWSTR_TEXTCALLBACK。
cchTextMax
读取文本时的缓冲区大小。
iImage
图片列表中此元素图标的索引。
lParam
特定于此元素的 32 位值。
元素动作
LVM_INSERTITEM 插入元素
LVM_DELETEITEM 删除一个元素
LVM_DELETEALLITEMS 删除所有元素
LVM_GETITEMW 读取元素的属性
LVM_GETITEMTEXT 读取元素的文本
LVM_SETITEMW 更改
LVM_SETITEMTEXT 改为文字
在插入多个项目之前,将向 ListView 发送一条LVM_SETITEMCOUNT 消息,指示最终将包含多少个项目。这允许 ListView 优化其内存分配和释放。 ListView 包含多少元素可以通过LVM_GETITEMCOUNT 确定。
编辑选定元素
int Pos = -1;
LVITEMW Item;
Pos = ListView_GetNextItem(hwndList, Pos, LVNI_SELECTED);
while (Pos> = 0)
{
Item.iItem = Pos;
Item.iSubItem = 0;
ListView_GetItem(hwndList, & Item);
TuWasMitElement((Element Type * ) Item.lParam);
Pos = ListView_GetNextItem(hwndList, Pos, LVNI_SELECTED);
}
活动
ListView 将WM_NOTIFY 消息发送到父窗口。该代码可以采用以下值:
消息............描述
LVN_BEGINDRAG.............启动拖放操作
LVN_BEGINRDRAG.............用鼠标右键开始拖放动作
LVN_BEGINLABELEDIT....开始编辑标签
LVN_ENDLABELEDIT.......结束标签编辑
LVN_DELETEITEM.............报告项目被删除
LVN_DELETEALLITEMS..报告所有项目都已删除
LVN_COLUMNCLICK......表示用户点击了报表显示的标题
LVN_GETDISPINFO.......控件从父窗口请求有关演示的信息
LVN_SETDISPINFO.......该项目的父窗口信息必须更新
LVN_INSERTITEM........表示插入一个item
LVN_ITEMCHANGED.....表示某项已更改
LVN_ITEMCHANGING....表示项目的预期更改
LVN_KEYDOWN.............按键被按下
编辑标签
列表视图必须是使用LVS_EDITLABELS 样式创建的。然后可以单击标签并接受输入。但是,输入会在之后立即被丢弃。要允许更改标签,您只需捕获WM_NOTIFY 并返回TRUE。为了访问中间输入的文本,访问项目的文本。该示例在消息框中显示了输入。
case WM_NOTIFY:
switch (((LPNMHDR) lParam) -> code)
{
case LVN_ENDLABELEDIT:
pItem = (NMLVDISPINFO) lParam;
MessageBox (hWnd, pItem-> item.pszText, "entry", MB_OK);
return TRUE;
如果编辑被中止,pszText 元素将为 0。
如果您想阻止编辑,消息LVN_BEGINLABELEDIT 将被捕获并返回TRUE。在这里,同样可以通过lParam 以相同的方式访问该项目,因此例如可以排除某个项目组。
点击ListView中的列标题
case WM_NOTIFY:
switch (((LPNMHDR) lParam) -> code)
{
case LVN_COLUMNCLICK:
ColumnNr = ((LPNMLISTVIEW) lParam) -> iSubItem;
.....
选择事件
LVN_ITEMACTIVATE 事件在用户激活项目时发送。与其他 ListView 事件一样,它作为WM_NOTIFY 消息的一部分实现窗口功能。
case WM_NOTIFY:
switch (((LPNMHDR) lParam) -> code)
{
case LVN_ITEMACTIVATE:
HWND hwndFrom = (HWND) ((LPNMHDR) lParam) -> hwndFrom;MarkedItemIndex =
ListView_GetNextItem(hwndFrom, -1, LVNI_SELECTED);
.....
LVM_GETSELECTEDCOUNT 消息可用于确定已激活的项目数量。 LVM_GETNEXTITEM 消息与 LVNI_SELECTED 属性一起发送,并且所有项目都已被编辑。