由于CListCtrl良好的数据展示形式和便捷的操作,所以我们在编程工作中会经常用到,网上找到一片不错的总结,估计对于一般的使用场景够用的。还有其他需求,我们可以再探索讨论。
以下未经说明,listctrl默认view 风格为report
1
. CListCtrl 风格
LVS_ICON: 为每个item显示大图标
LVS_SMALLICON: 为每个item显示小图标
LVS_LIST: 显示一列带有小图标的item
LVS_REPORT: 显示item详细资料
直观的理解:windows资源管理器,“查看”标签下的“大图标,小图标,列表,详细资料”
2
. 设置listctrl 风格及扩展风格
LONG lStyle;
lStyle
=
GetWindowLong(m_list.m_hWnd, GWL_STYLE);
//
获取当前窗口style
lStyle
&=
~
LVS_TYPEMASK;
//
清除显示方式位
lStyle
|=
LVS_REPORT;
//
设置style
SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);
//
设置style
DWORD dwStyle
=
m_list.GetExtendedStyle();
dwStyle
|=
LVS_EX_FULLROWSELECT;
//
选中某行使整行高亮(只适用与report风格的listctrl)
dwStyle
|=
LVS_EX_GRIDLINES;
//
网格线(只适用与report风格的listctrl)
dwStyle
|=
LVS_EX_CHECKBOXES;
//
item前生成checkbox控件
m_list.SetExtendedStyle(dwStyle);
//
设置扩展风格
注:listview的style请查阅msdn
http:
//
msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp
3
. 插入数据
m_list.InsertColumn(
0
,
"
ID
"
, LVCFMT_LEFT,
40
);
//
插入列
m_list.InsertColumn(
1
,
"
NAME
"
, LVCFMT_LEFT,
50
);
int
nRow
=
m_list.InsertItem(
0
, “
11
”);
//
插入行
m_list.SetItemText(nRow,
1
, “jacky”);
//
设置数据
4
. 一直选中item
选中style中的Show selection always,或者在上面第2点中设置LVS_SHOWSELALWAYS
5
. 选中和取消选中一行
int
nIndex
=
0
;
//
选中
m_list.SetItemState(nIndex, LVIS_SELECTED
|
LVIS_FOCUSED, LVIS_SELECTED
|
LVIS_FOCUSED);
//
取消选中
m_list.SetItemState(nIndex,
0
, LVIS_SELECTED
|
LVIS_FOCUSED);
6
. 得到listctrl中所有行的checkbox的状态
m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
CString str;
for
(
int
i
=
0
; i {
if
( m_list.GetItemState(i, LVIS_SELECTED)
==
LVIS_SELECTED
||
m_list.GetCheck(i))
{
str.Format(_T(
"
第%d行的checkbox为选中状态
"
), i);
AfxMessageBox(str);
}
}
7
. 得到listctrl中所有选中行的序号
方法一:
CString str;
for
(
int
i
=
0
; i {
if
( m_list.GetItemState(i, LVIS_SELECTED)
==
LVIS_SELECTED )
{
str.Format(_T(
"
选中了第%d行
"
), i);
AfxMessageBox(str);
}
}
方法二:
POSITION pos
=
m_list.GetFirstSelectedItemPosition();
if
(pos
==
NULL)
TRACE0(
"
No items were selected!\n
"
);
else
{
while
(pos)
{
int
nItem
=
m_list.GetNextSelectedItem(pos);
TRACE1(
"
Item %d was selected!\n
"
, nItem);
//
you could do your own processing on nItem here
}
}
8
. 得到item的信息
TCHAR szBuf[
1024
];
LVITEM lvi;
lvi.iItem
=
nItemIndex;
lvi.iSubItem
=
0
;
lvi.mask
=
LVIF_TEXT;
lvi.pszText
=
szBuf;
lvi.cchTextMax
=
1024
;
m_list.GetItem(
&
lvi);
关于得到设置item的状态,还可以参考msdn文章
Q173242: Use Masks to Set
/
Get Item States
in
CListCtrl
http:
//
support.microsoft.com/kb/173242/en-us
9
. 得到listctrl的所有列的header字符串内容
LVCOLUMN lvcol;
char
str[
256
];
int
nColNum;
CString strColumnName[
4
];
//
假如有4列
nColNum
=
0
;
lvcol.mask
=
LVCF_TEXT;
lvcol.pszText
=
str;
lvcol.cchTextMax
=
256
;
while
(m_list.GetColumn(nColNum,
&
lvcol))
{
strColumnName[nColNum]
=
lvcol.pszText;
nColNum
++
;
}
10
. 使listctrl中一项可见,即滚动滚动条
m_list.EnsureVisible(i, FALSE);
11
. 得到listctrl列数
int
nHeadNum
=
m_list.GetHeaderCtrl()
->
GetItemCount();
12
. 删除所有列
方法一:
while
( m_list.DeleteColumn (
0
))
因为你删除了第一列后,后面的列会依次向上移动。
方法二:
int
nColumns
=
4
;
for
(
int
i
=
nColumns
-
1
; i
>=
0
; i
--
)
m_list.DeleteColumn (i);
13
. 得到单击的listctrl的行列号
添加listctrl控件的NM_CLICK消息相应函数
void
CTest6Dlg::OnClickList1(NMHDR
*
pNMHDR, LRESULT
*
pResult)
{
//
方法一:
/*
DWORD dwPos = GetMessagePos();
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
m_list.ScreenToClient(&point);
LVHITTESTINFO lvinfo;
lvinfo.pt = point;
lvinfo.flags = LVHT_ABOVE;
int nItem = m_list.SubItemHitTest(&lvinfo);
if(nItem != -1)
{
CString strtemp;
strtemp.Format("单击的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);
AfxMessageBox(strtemp);
}
*/
//
方法二:
/*
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if(pNMListView->iItem != -1)
{
CString strtemp;
strtemp.Format("单击的是第%d行第%d列",
pNMListView->iItem, pNMListView->iSubItem);
AfxMessageBox(strtemp);
}
*/
*
pResult
=
0
;
}
14
. 判断是否点击在listctrl的checkbox上
添加listctrl控件的NM_CLICK消息相应函数
void
CTest6Dlg::OnClickList1(NMHDR
*
pNMHDR, LRESULT
*
pResult)
{
DWORD dwPos
=
GetMessagePos();
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
m_list.ScreenToClient(
&
point);
LVHITTESTINFO lvinfo;
lvinfo.pt
=
point;
lvinfo.flags
=
LVHT_ABOVE;
UINT nFlag;
int
nItem
=
m_list.HitTest(point,
&
nFlag);
//
判断是否点在checkbox上
if
(nFlag
==
LVHT_ONITEMSTATEICON)
{
AfxMessageBox(
"
点在listctrl的checkbox上
"
);
}
*
pResult
=
0
;
}
15
. 右键点击listctrl的item弹出菜单
添加listctrl控件的NM_RCLICK消息相应函数
void
CTest6Dlg::OnRclickList1(NMHDR
*
pNMHDR, LRESULT
*
pResult)
{
NM_LISTVIEW
*
pNMListView
=
(NM_LISTVIEW
*
)pNMHDR;
if
(pNMListView
->
iItem
!=
-
1
)
{
DWORD dwPos
=
GetMessagePos();
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
CMenu menu;
VERIFY( menu.LoadMenu( IDR_MENU1 ) );
CMenu
*
popup
=
menu.GetSubMenu(
0
);
ASSERT( popup
!=
NULL );
popup
->
TrackPopupMenu(TPM_LEFTALIGN
|
TPM_RIGHTBUTTON, point.x, point.y,
this
);
}
*
pResult
=
0
;
}
16
. item切换焦点时(包括用键盘和鼠标切换item时),状态的一些变化顺序
添加listctrl控件的LVN_ITEMCHANGED消息相应函数
void
CTest6Dlg::OnItemchangedList1(NMHDR
*
pNMHDR, LRESULT
*
pResult)
{
NM_LISTVIEW
*
pNMListView
=
(NM_LISTVIEW
*
)pNMHDR;
//
TODO: Add your control notification handler code here
CString sTemp;
if
((pNMListView
->
uOldState
&
LVIS_FOCUSED)
==
LVIS_FOCUSED
&&
(pNMListView
->
uNewState
&
LVIS_FOCUSED)
==
0
)
{
sTemp.Format(
"
%d losted focus
"
,pNMListView
->
iItem);
}
else
if
((pNMListView
->
uOldState
&
LVIS_FOCUSED)
==
0
&&
(pNMListView
->
uNewState
&
LVIS_FOCUSED)
==
LVIS_FOCUSED)
{
sTemp.Format(
"
%d got focus
"
,pNMListView
->
iItem);
}
if
((pNMListView
->
uOldState
&
LVIS_SELECTED)
==
LVIS_SELECTED
&&
(pNMListView
->
uNewState
&
LVIS_SELECTED)
==
0
)
{
sTemp.Format(
"
%d losted selected
"
,pNMListView
->
iItem);
}
else
if
((pNMListView
->
uOldState
&
LVIS_SELECTED)
==
0
&&
(pNMListView
->
uNewState
&
LVIS_SELECTED)
==
LVIS_SELECTED)
{
sTemp.Format(
"
%d got selected
"
,pNMListView
->
iItem);
}
*
pResult
=
0
;
}
17
. 得到另一个进程里的listctrl控件的item内容
http:
//
www.codeproject.com/threads/int64_memsteal.asp
18
. 选中listview中的item
Q131284: How To Select a Listview Item Programmatically
http:
//
support.microsoft.com/kb/131284/en-us
19
. 如何在CListView中使用CListCtrl的派生类
http:
//
www.codeguru.com/cpp/controls/listview/introduction/article.php/c919/
20
. listctrl的subitem添加图标
m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);
m_list.SetItem(..);
//
具体参数请参考msdn
21
. 在CListCtrl显示文件,并根据文件类型来显示图标
网上找到的代码,share
BOOL CTest6Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
HIMAGELIST himlSmall;
HIMAGELIST himlLarge;
SHFILEINFO sfi;
char
cSysDir[MAX_PATH];
CString strBuf;
memset(cSysDir,
0
, MAX_PATH);
GetWindowsDirectory(cSysDir, MAX_PATH);
strBuf
=
cSysDir;
sprintf(cSysDir,
"
%s
"
, strBuf.Left(strBuf.Find(
"
file://%22)+1/));
himlSmall
=
(HIMAGELIST)SHGetFileInfo ((LPCSTR)cSysDir,
0
,
&
sfi,
sizeof
(SHFILEINFO),
SHGFI_SYSICONINDEX
|
SHGFI_SMALLICON );
himlLarge
=
(HIMAGELIST)SHGetFileInfo((LPCSTR)cSysDir,
0
,
&
sfi,
sizeof
(SHFILEINFO),
SHGFI_SYSICONINDEX
|
SHGFI_LARGEICON);
if
(himlSmall
&&
himlLarge)
{
::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,
(WPARAM)LVSIL_SMALL, (LPARAM)himlSmall);
::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,
(WPARAM)LVSIL_NORMAL, (LPARAM)himlLarge);
}
return
TRUE;
//
return TRUE unless you set the focus to a control
}
void
CTest6Dlg::AddFiles(LPCTSTR lpszFileName, BOOL bAddToDocument)
{
int
nIcon
=
GetIconIndex(lpszFileName, FALSE, FALSE);
CString strSize;
CFileFind filefind;
//
get file size
if
(filefind.FindFile(lpszFileName))
{
filefind.FindNextFile();
strSize.Format(
"
%d
"
, filefind.GetLength());
}
else
strSize
=
"
0
"
;
//
split path and filename
CString strFileName
=
lpszFileName;
CString strPath;
int
nPos
=
strFileName.ReverseFind(
'
\\
'
);
if
(nPos
!=
-
1
)
{
strPath
=
strFileName.Left(nPos);
strFileName
=
strFileName.Mid(nPos
+
1
);
}
//
insert to list
int
nItem
=
m_list.GetItemCount();
m_list.InsertItem(nItem, strFileName, nIcon);
m_list.SetItemText(nItem,
1
, strSize);
m_list.SetItemText(nItem,
2
, strFileName.Right(
3
));
m_list.SetItemText(nItem,
3
, strPath);
}
int
CTest6Dlg::GetIconIndex(LPCTSTR lpszPath, BOOL bIsDir, BOOL bSelected)
{
SHFILEINFO sfi;
memset(
&
sfi,
0
,
sizeof
(sfi));
if
(bIsDir)
{
SHGetFileInfo(lpszPath,
FILE_ATTRIBUTE_DIRECTORY,
&
sfi,
sizeof
(sfi),
SHGFI_SMALLICON
|
SHGFI_SYSICONINDEX
|
SHGFI_USEFILEATTRIBUTES
|
(bSelected
?
SHGFI_OPENICON :
0
));
return
sfi.iIcon;
}
else
{
SHGetFileInfo (lpszPath,
FILE_ATTRIBUTE_NORMAL,
&
sfi,
sizeof
(sfi),
SHGFI_SMALLICON
|
SHGFI_SYSICONINDEX
|
SHGFI_USEFILEATTRIBUTES
|
(bSelected
?
SHGFI_OPENICON :
0
));
return
sfi.iIcon;
}
return
-
1
;
}
22
. listctrl内容进行大数据量更新时,避免闪烁
m_list.SetRedraw(FALSE);
//
更新内容
m_list.SetRedraw(TRUE);
m_list.Invalidate();
m_list.UpdateWindow();
本文来自CSDN博客,转载请标明出处:http:
//
blog.csdn.net/xiaolan458/archive/2008/12/10/3488236.aspx