更新日期:2011-1-10
示例代码:demo.zip (请不要使用下载工具,否则可能出错)
测试环境:VC6.0+WinXP
图片预览:
CListCtrl 使用技巧:(这一篇文章写得很好,极力推荐)
http://blog.csdn.net/lixiaosan/archive/2006/04/07/653563.aspx
以下是网上收集的资料,都很不错:(请不要使用下载工具,否则可能出错)
http://cid-3ba16e78a53d2d3d.office.live.com/self.aspx/VC/ClistCtrl-help.zip
基本样式和扩张样式
━━━━━━━━━━━━━━━━━━━━━━━━
(1)基本样式
LVS_ICON 大图标显示方式;
LVS_LIST 列表显示方式;
LVS_SMALLICON 小图标显示方式;
LVS_REPORT 以详细资料即报告方式显示;
LVS_ALIGNLEFT 表项的大小图标以左对齐方式显示;
LVS_ALIGNTOP 表项的大小图标以顶对齐方式显示;
LVS_AUTOARRANGE 表项的大小图标以自动排列方式显示;
LVS_EDITLABELS 设置表项文本可以编辑,父窗口必须设有LVN_ENDLABELEDIT风格;
LVS_NOCOLUMNHEADER 在详细资料方式时不显示列表头;
LVS_NOLABELWRAP 以单行方式显示图标的文本项;
LVS_NOSCROLL 用来屏蔽滚动条;
LVS_NOSORTHEADER 列表头不能用作按钮功能;
LVS_OWNERDRAWFIXED 在详细列表方式时允许自绘窗口;
LVS_SHAREIMAGELISTS 共享图像列表方式,如果一个程序里有两个Listctrl同用一个HIMAGELIST,则其中一个摧毁不会影响另外一个,Specifies that the control does not take ownership of the image lists assigned to it (that is, it does not destroy the image lists when it is destroyed). This style enables the same image lists to be used with multiple list view controls.
LVS_SHOWSELALWAYS 一直显示被选中表项方式;
LVS_SINGLESEL 在某一时刻只能有一项被选中;
LVS_SORTASCENDING 表项排序时是基于表项文本的升序方式;
LVS_SORTDESCENDING 表项排序时是基于表项文本的降序方式;
设置方法:
LONG lStyle;
lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //获取当前窗口style
lStyle &= ~LVS_TYPEMASK; //清除显示方式位
lStyle |=LVS_ICON ; //设置style
SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//设置style
(2)扩展样式,
CListCtrl控件的扩展样式,用SetExtendedStyle来改变
LVS_EX_GRIDLINES //绘制表格线(report风格时)
LVS_EX_FULLROWSELECT //选择整行(report风格时)
LVS_EX_SUBITEMIMAGES //子项目图标列表
LVS_EX_CHECKBOXES //带复选框
LVS_EX_TRACKSELECT //自动换行
LVS_EX_HEADERDRAGDROP //报表头可以拖拽
LVS_EX_ONECLICKACTIVATE //单击激活
LVS_EX_TWOCLICKACTIVATE //双击激活
LVS_EX_FLATSB //扁平滚动条
LVS_EX_REGIONAL
LVS_EX_INFOTIP
LVS_EX_UNDERLINEHOT
LVS_EX_UNDERLINECOLD
LVS_EX_MULTIWORKAREAS //多工作区
设置方法:
DWORD dwStyle = m_ListCtrl.GetExtendedStyle(); //获取当前扩展样式
dwStyle |= LVS_EX_FULLROWSELECT; //选中某行使整行高亮(report风格时)
dwStyle |= LVS_EX_GRIDLINES; //网格线(report风格时)
m_ListCtrl.SetExtendedStyle(dwStyle); //设置扩展风格
初始化CListCtrl
━━━━━━━━━━━━━━━━━━━━━━━━
BOOL CDemoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
/*
//自定义图标
m_imagelist.Create(16,16,ILC_COLORDDB,2,2); //创建CImageList 16,16是图标的大小
m_imagelist.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME)); //向CImageList中添加图标
m_imagelist.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));
m_ListCtrl.SetImageList(&m_imagelist,LVSIL_SMALL);//把CListCtrl中的CImageList联
*/
//设置基本样式
LONG lStyle;
lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //获取当前窗口style
lStyle |=LVS_REPORT ; //以详细资料即报告方式显示;
lStyle |=LVS_SHOWSELALWAYS ; //一直显示被选中表项方式;
SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//设置style
//设置扩展样式
DWORD dwStyle = m_ListCtrl.GetExtendedStyle(); //获取当前扩展样式
dwStyle |= LVS_EX_FULLROWSELECT; //选中某行使整行高亮(report风格时)
dwStyle |= LVS_EX_GRIDLINES; //网格线(report风格时)
m_ListCtrl.SetExtendedStyle(dwStyle); //设置扩展风格
SHFILEINFO shFinfo;
//获取系统小图标
HIMAGELIST hImageListSmall=(HIMAGELIST)::SHGetFileInfo(_T("c://"),0,&shFinfo,sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX| SHGFI_SMALLICON);
//获取系统大图标
HIMAGELIST hImageListLarge=(HIMAGELIST)::SHGetFileInfo(_T("c://"),0,&shFinfo,sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX| SHGFI_ICON);
m_ListCtrl.SetImageList(CImageList::FromHandle(hImageListSmall),LVSIL_SMALL);
m_ListCtrl.SetImageList(CImageList::FromHandle(hImageListLarge),LVSIL_NORMAL);
// ::SendMessage(m_ListCtrl.m_hWnd, LVM_SETIMAGELIST, (WPARAM)LVSIL_NORMAL, (LPARAM)hImageList);
//设置列
m_ListCtrl.InsertColumn(0, "第一列", LVCFMT_LEFT, 150);
m_ListCtrl.InsertColumn(1, "第二列", LVCFMT_LEFT, 150);
m_ListCtrl.InsertColumn(2, "第三列", LVCFMT_LEFT, 150);
//添加c盘目录到CListCtrl
EnumFiles("c:",m_ListCtrl);
//添加数据
CString strData[3][3] =
{
{ _T("Washington"), _T("George"), _T("1789-1797") },
{ _T("Adams"), _T("John"), _T("1797-1801") },
{ _T("Jefferson"), _T("Thomas"), _T("1801-1809") }
};
for (int i=0; i<3; i++)
{
m_ListCtrl.InsertItem(i, strData[i][0]);
m_ListCtrl.SetItemText(i, 1, strData[i][1]);
m_ListCtrl.SetItemText(i, 2, strData[i][2]);
m_ListCtrl.SetItemData(i, i);
}
return TRUE; // return TRUE unless you set the focus to a control
}
以下展示4种视图间的切换:
━━━━━━━━━━━━━━━━━━━━━━━━
void CDemoDlg::OnRadio1()
{
LONG lStyle;
lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //获取当前窗口style
lStyle &= ~LVS_TYPEMASK; //清除显示方式位
lStyle |=LVS_ICON ; //设置style
SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//设置style
}
void CDemoDlg::OnRadio2()
{
LONG lStyle;
lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //获取当前窗口style
lStyle &= ~LVS_TYPEMASK; //清除显示方式位
lStyle |=LVS_LIST ; //修改style
SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//设置style
}
void CDemoDlg::OnRadio3()
{
//另外一种简单的方法
m_ListCtrl.ModifyStyle(LVS_TYPEMASK,LVS_SMALLICON);
}
void CDemoDlg::OnRadio4()
{
LONG lStyle;
lStyle=GetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE); //获取当前窗口style
lStyle &= ~LVS_TYPEMASK; //清除显示方式位
lStyle |=LVS_REPORT ; //设置style
SetWindowLong(m_ListCtrl.m_hWnd, GWL_STYLE, lStyle); //设置style
}
━━━━━━━━━━━━━━━━━━━━━━━━
/****************************************************************************
插入一行
****************************************************************************/
void CDemoDlg::OnButton1()
{
//插入一行数据,方法一
int nRow = m_ListCtrl.InsertItem(2,_T("text1"),0); //参数(行数,标题,图标索引)
m_ListCtrl.SetItemText(nRow, 1, _T("text2")); //参数(行数,此行的哪一列,文本)
m_ListCtrl.SetItemText(nRow, 2, _T("text3")); //参数(行数,此行的哪一列,文本)
//插入一行数据,方法二
LVITEM lvi = {0}; //定义一个数据项
lvi.mask = LVIF_TEXT ; //标志位 文本
lvi.iItem = 3 ; //此项是3行,可修改为想要插入的行
lvi.iSubItem = 0; //此项是第几列的数据
lvi.iImage =1; //第几个图标
lvi.pszText =_T("jacky_qiu"); //文本
m_ListCtrl.InsertItem(&lvi);
// ::SendMessage(m_ListCtrl.m_hWnd, LVM_INSERTITEM, 0,(LPARAM)&lvi);
//当插入item后调用SetColumnWidth可以自动变宽度大小
m_ListCtrl.SetColumnWidth ( 0, LVSCW_AUTOSIZE_USEHEADER );
m_ListCtrl.SetColumnWidth ( 1, LVSCW_AUTOSIZE_USEHEADER );
m_ListCtrl.SetColumnWidth ( 2, LVSCW_AUTOSIZE_USEHEADER );
}
━━━━━━━━━━━━━━━━━━━━━━━━
/****************************************************************************
修改一行
****************************************************************************/
void CDemoDlg::OnButton2()
{
//修改某行某列的数据
LVITEM lvi = {0}; //定义一个数据项
lvi.mask = LVIF_TEXT ; //标志位 (指明需要修改什么)
lvi.iItem = 2 ; //需要修改的项的索引
lvi.iSubItem = 0; //此项是第几列的数据
lvi.iImage =1; //第几个图标
lvi.pszText =_T("修改"); //修改的文本
//mfc
m_ListCtrl.SetItem(&lvi); //修改这一项,此项一定要存在
//win32 api
::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, NULL, (LPARAM)&lvi);
}
━━━━━━━━━━━━━━━━━━━━━━━━
/****************************************************************************
单选情况下删除一行
****************************************************************************/
void CDemoDlg::OnButton3()
{
m_ListCtrl.DeleteItem(2);
}
━━━━━━━━━━━━━━━━━━━━━━━━
/****************************************************************************
删除选择的多行
****************************************************************************/
void CDemoDlg::OnButton6()
{
//删除选中的多行
POSITION sSelPos = NULL;
int nSelItem;
while(sSelPos = m_ListCtrl.GetFirstSelectedItemPosition())
{
nSelItem = m_ListCtrl.GetNextSelectedItem(sSelPos);
if(nSelItem >= 0 && nSelItem
}
}
━━━━━━━━━━━━━━━━━━━━━━━━
/****************************************************************************
获取选中行
****************************************************************************/
void CDemoDlg::OnButton5()
{
/*
{
int SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,-1,MAKELPARAM(LVNI_SELECTED,0));
if (SelectItem==-1)
{
::MessageBox(m_hWnd,TEXT("请至少选择一个文件"),NULL,MB_OK);
return;
}
do //获取选中的多个项;
{
}
while(-1!=(SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,SelectItem,MAKELPARAM(LVNI_SELECTED,0))));
}
*/
//获得选中的行(选中多行)
POSITION pos=m_ListCtrl.GetFirstSelectedItemPosition();
if(pos!= NULL)
{
while (pos)
{
int nItem=m_ListCtrl.GetNextSelectedItem(pos);
trace("选中了",nItem);
}
}
//获取选中的多个项;
int SelectItem=-1;
while(-1!=(SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,SelectItem,MAKELPARAM(LVNI_SELECTED,0))))
{
trace("选中了:",SelectItem);
}
//判断是否一项也没有选中
if( -1!=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,-1,MAKELPARAM(LVNI_SELECTED,0)))
{
trace("选中了至少一项");
}
else
{
trace("没有选中一项");
}
//如果ListCtrl是单选的,就用这种方式判断选中的项
SelectItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_GETNEXTITEM,-1,MAKELPARAM(LVNI_SELECTED,0));
if (SelectItem!=-1)
{
//get the item
TCHAR szBuf[1024];
LVITEM lvi;
lvi.iItem = SelectItem;
lvi.pszText = szBuf;
lvi.cchTextMax = sizeof(szBuf)/sizeof(TCHAR);
lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE|LVIF_DI_SETITEM;
//第一列
lvi.iSubItem = 0;
::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM)&lvi);
trace(SelectItem,lvi.iSubItem,szBuf);
//第二列
lvi.iSubItem = 1;
::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM)&lvi);
trace(SelectItem,lvi.iSubItem,szBuf);
{
TCHAR szBuf[1024];
LVITEM lvi;
lvi.pszText = szBuf;
lvi.cchTextMax =sizeof(szBuf)/sizeof(TCHAR);
lvi.iSubItem =0;
lvi.mask = LVIF_TEXT;
int count=(int)::SendMessage(m_ListCtrl.m_hWnd,LVM_GETITEMCOUNT,0, 0);
for(int i=0; i
::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)&lvi);
trace(SelectItem,lvi.iSubItem,lvi.pszText);
}
}
{
int count=(int)::SendMessage(m_ListCtrl.m_hWnd,LVM_GETITEMCOUNT,0, 0);
for(int i=0; i
TCHAR szBuf[MAX_PATH];
m_ListCtrl.GetItemText(i,0,szBuf,sizeof(szBuf)/sizeof(TCHAR));
trace(szBuf);
}
}
}
}
━━━━━━━━━━━━━━━━━━━━━━━━
void CDemoDlg::OnFind()
{
//寻找一个item
LVFINDINFO FindInfo;
FindInfo.flags = LVFI_STRING ;
FindInfo.psz ="windows";
// int nItem=::SendMessage(m_ListCtrl.m_hWnd,LVM_FINDITEM,-1,(LPARAM)&FindInfo);
int nItem=m_ListCtrl.FindItem(&FindInfo);
if (nItem!=-1)
{
tracef("找到 %s,在 %d 行",FindInfo.psz,nItem);
}
else
{
tracef("找不到 %s ",FindInfo.psz);
}
}
━━━━━━━━━━━━━━━━━━━━━━━━
void CDemoDlg::OnButton7()
{
//获得一项的图标
LVITEM lvi={0};
lvi.iItem = 6; //获取第6项
lvi.mask =LVIF_IMAGE;
m_ListCtrl.GetItem(&lvi);
tracef("image index : %d",lvi.iImage);
}
━━━━━━━━━━━━━━━━━━━━━━━━
void CDemoDlg::OnButton8()
{
//需要设置dwStyle |= LVS_SHOWSELALWAYS;
//当List control获得焦点时 才会高亮度成蓝色的,
//如果List control没有焦点,选中的项只是灰色的
//选中一个item,方法一
m_ListCtrl.SetItemState(1,LVIS_SELECTED,LVIS_SELECTED);
//选中一个item,方法二
LVITEM lviItem;
lviItem.stateMask=LVIS_SELECTED ;
lviItem.state=LVIS_SELECTED;
::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEMSTATE, 2,(LPARAM) &lviItem);
//选中一个item,方法三
LVITEM lvi={0};
lvi.iItem = 3;
lvi.mask = LVIF_STATE;
lvi.stateMask=LVIS_SELECTED ;
lvi.state=LVIS_SELECTED;
::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, 0,(LPARAM) &lvi);
{
//取消选中第5项目,方法一
m_ListCtrl.SetItemState(5,0,LVIS_SELECTED);
//取消选中第4项目,方法二
LVITEM lviItem;
lviItem.stateMask=LVIS_SELECTED ;
lviItem.state=0;
::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEMSTATE, 4,(LPARAM) &lviItem);
//取消选中第6项目,方法三
LVITEM lvi={0};
lvi.iItem =6;
lvi.mask = LVIF_STATE;
lvi.stateMask=LVIS_SELECTED ;
lvi.state=0;
::SendMessage(m_ListCtrl.m_hWnd, LVM_SETITEM, 0,(LPARAM) &lvi);
}
}
━━━━━━━━━━━━━━━━━━━━━━━━
void CDemoDlg::OnButton13()
{
//获取第2行的选中状态,方法一
LVITEM lvi={0};
lvi.iItem = 2;
lvi.mask = LVIF_STATE;
lvi.stateMask=LVIS_SELECTED ; //lvi.mask 必须指定LVIF_STATE
// ::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEM, 0,(LPARAM) &lvi);
m_ListCtrl.GetItem(&lvi);
if (lvi.state|LVIS_SELECTED==1)
{
trace("第2行 select");
}
else
{
trace("第2行 no select");
}
//获取第3行的选中状态,方法二
int state=(int)::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEMSTATE,3,(LPARAM) LVIS_SELECTED);
if (state|LVIS_SELECTED==1)
{
trace("第3行 select");
}
else
{
trace("第3行 no select");
}
}
━━━━━━━━━━━━━━━━━━━━━━━━
//鼠标点击
void CDemoDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if(pNMListView->iItem != -1) //假如没有选中一项
{
tracef("单击的是第%d行第%d列",pNMListView->iItem, pNMListView->iSubItem);
}
/*
NM_LISTVIEW* pList = (NM_LISTVIEW*)pNMHDR;
if(-1 != pList->iItem)
{
static CEdit* pEdit=NULL;
CRect rect;
m_ListCtrl.GetSubItemRect(pList->iItem, pList->iSubItem, LVIR_BOUNDS, rect);
if(NULL == pEdit)
{
pEdit = new CEdit();
pEdit->Create(ES_AUTOHSCROLL|WS_CHILD, rect, &m_ListCtrl, 34234);
pEdit->SetFont(m_ListCtrl.GetFont());
pEdit->SetWindowText(m_ListCtrl.GetItemText(pList->iItem, pList->iSubItem));
}
pEdit->MoveWindow(rect);
pEdit->ShowWindow(SW_SHOW);
}
*/
*pResult = 0;
}
void CDemoDlg::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if(pNMListView->iItem != -1) //假如选中一项
{
tracef("双击的是第%d行第%d列",pNMListView->iItem, pNMListView->iSubItem);
}
*pResult = 0;
}
━━━━━━━━━━━━━━━━━━━━━━━━
/****************************************************************************
获取item的矩形
****************************************************************************/
void CDemoDlg::OnButton10()
{
RECT ItemRect;
// ItemRect.left=LVIR_LABEL ; //Returns the bounding rectangle of the item text.
// ItemRect.left=LVIR_BOUNDS ; //Returns the bounding rectangle of the entire item, including the icon and label.
// ItemRect.left=LVIR_ICON ; //Returns the bounding rectangle of the icon or small icon.
ItemRect.left=LVIR_SELECTBOUNDS;//Returns the union of the LVIR_ICON and LVIR_LABEL rectangles, but excludes columns in details view.
::SendMessage(m_ListCtrl.m_hWnd, LVM_GETITEMRECT , 1,(LPARAM)&ItemRect);
HeightLightRect(m_ListCtrl.m_hWnd,ItemRect,true);
trace(ItemRect);
}
━━━━━━━━━━━━━━━━━━━━━━━━
void CDemoDlg::OnButton11()
{
m_ListCtrl.SetBkColor(RGB(200, 200, 200)); //设置背景颜色
m_ListCtrl.SetTextBkColor(RGB(200, 200, 200)); //设置文本背景颜色
m_ListCtrl.SetTextColor(RGB(10, 10, 80)); //设置文本颜色
m_ListCtrl.Update(0);
}
━━━━━━━━━━━━━━━━━━━━━━━━
void CDemoDlg::OnButton15()
{
//使某项可见,(出现在窗口里)
// m_ListCtrl.EnsureVisible(1,FALSE);
::SendMessage(m_ListCtrl.m_hWnd, LVM_ENSUREVISIBLE, 10,(LPARAM) false);
m_ListCtrl.SetItemState(10,LVIS_SELECTED,LVIS_SELECTED); //选中
}
━━━━━━━━━━━━━━━━━━━━━━━━
/****************************************************************************
右键点击时出现编辑框,
属性必须设置为 LVS_EDITLABELS
****************************************************************************/
void CDemoDlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
UINT nFlag;
CPoint point;
GetCursorPos(&point);
m_ListCtrl.ScreenToClient(&point);
int nItem = m_ListCtrl.HitTest(point, &nFlag);
if (nItem >= 0)
m_ListCtrl.EditLabel(nItem);
*pResult = 0;
}
//编辑后修改文本
void CDemoDlg::OnEndlabeleditList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LVITEMA item = pDispInfo->item;
CString str = item.pszText;
str.TrimLeft();
str.TrimRight();
if (str.GetLength() > 0)
m_ListCtrl.SetItemText(item.iItem,item.iSubItem,item.pszText);
*pResult = 0;
}
推荐:
━━━━━━━━━━━━━━━━━━━━━━━━
谈老师的BLOG (佛教大德)
狮姐的博客(狮子窝,学佛与灵魂之探究)
大方广(学习传统文化)
慈善点击(轻松一点,行善积德,何乐不为)
电影《地球公民》(揭示不为人知的一面)
心向光明 远离邪淫(现世警钟,不可不看)
戒淫(上篇)(正淫节欲,戒除邪淫)
戒淫(中篇)(纵欲之乐,忧患随之)
公民教育——命由我造