VC控件——ListControl
2016-04-05 17:03
344 查看
ListCtrl控件由四种列表的显示方式构成:
Icons: 控件显示项的列表,使用32*32(像素)大小的icons
Small
Icons:和剩下的两项相似的想法,它使用16*16(像素)大小的图标来显示一个单一的列表项
List:这种列表,使用small icons,也是组织列;这种情况下,在第二列填充之前必须填充第一列
Report:安排项的目的是提供列表开发者的信息
(1)
创建List Control
法1:列表初始化:
添加变量m_list .create(WS_CHILD|WS_VISIBLE,CRect(10,10,320,280),this,0x285;
创建控件的时候,增加LVS_ICON LVS_SMALLICON
LVS_REPORT LVS_REPORT等
除了常规的几种风格外,Win32类库为ListCtrl提供了扩展风格,提供了一个扩展风格,调用CListCtrl::SetExtendStyle()方法,它的语法为:
DWORD SetExtendedStyle(DWORD dwNewStyle);
LVS_ALIGNLEFT 显示格式是大图标或小图标时,标签放在图标的左边
LVS_ALIGNTOP 显示格式是大图标或小图标时,标题放在图标的上边
LVS_AUTOARRANGE 显示格式是大图标或小图标时,自动排列控件中的列表项
LVS_EDITLABELS 用户可以修改标签文本
LVS_ICON 指定大图标显示格式
LVS_LIST 指定列表显示格式
LVS_NOCOLUMNHEADER 在报表格式中不显示列的表头
LVS_NOLABELWRAP 显示格式是大图标时,使标签文本单行显示。默认是多行显示
LVS_NOSCROLL 列表视图控件无滚动条,此风格不能与LVS_LIST或LVS_REPORT组合使用
LVS_NOSORTHEADER 报表格式的列表视图控件的表头不能作为排序按钮使用
LVS_OWNERDRAWFIXED 由控件的拥有者负责绘制表项
LVS_REPORT 指定报表显示格式
LVS_SHAREIMAGELISTS 使列表视图共享图像序列
LVS_SHOWSELALWAYS 即使控件失去输入焦点,仍显示出项的选择状态
LVS_SINGLESEL 指定只能有一个列表项被选中。默认时可以多项选择
LVS_SMALLICON 指定小图标显示格式
LVS_SORTASCENDING 按升序排列列表项
LVS_SORTDESCENDING 按降序排列列表项
添加项(单元项):
结构体: typedefstruct
{
UINT mask;用来指定你想给当前项设置的类型。
int
iItem;指定改变项的索引,第一个item应该为0,第二个item为1等等。
int
iSubItem;当前值的的子项,如果当前项是主导项,iSumItem应该存储从0开始的数组
UINT state;
UINT stateMask;
LPTSTR pszText;
要显示项的字符串,你可以通过cchTextMask指定文本的长度
int cchTextMax;
int iImage;
LPARAM lParam;
} LVITEM,*LPLVITEM;
lvItem.mask=
LVIF_TEXT;
lvItem.iItem=0;
lvItem.iSubItem=0;
lvItem.pszText=
strNumber;m_list.InsertItem(&lvItem);
LVITEM结构体的值将决定新项的功能。例如,一旦增加了一个项,你可能想要准备删除前面的项、剪切和粘贴操作,在这种情况下,你应该将设置为LVIS_CUT;如果你想实现拖放操作,你可以设置LVIS_DROPHILIGHTED;如果想让项获得焦点,设置LVIS_FOCUSED;包含LVIS_SELECTED属性的情况下可以被选中
创建一个ListCtrl的列,
你可以使用CListCtrl::InsertColumn()方法,它的一种声明为:
int InsertColumn(int nCol, const LVCOLUMN* pColumn);
nCol:将要创建列的索引
pColumn:指向LVCOLUMN结构体指针,结构体定义如下:
typedefstruct
_LVCOLUMN {
UINT mask;用来指定你想要的列的属性
int
fmt;格式化列的文本(默认值LVCFMT_LEFT),居中(LVCFMT_CENTER),或者右对齐(LVCFMT_RIGHT)
int
cx;cx 用来指定列文本的宽度
LPTSTR pszText;pszText 是将要显示的列的字符串
int
cchTextMax;
int
iSubItem;
} LVCOLUMN, FAR*LPLVCOLUMN;
LVCOLUMN
lvColumn;
int
nCol; 例如
lvColumn.mask=
LVCF_FMT| LVCF_TEXT|
LVCF_WIDTH;
lvColumn.fmt=
LVCFMT_LEFT;
lvColumn.cx=120;
lvColumn.pszText=
TEXT("Full
Name");
nCol=
m_StoreItems.InsertColumn(0,&lvColumn);
你也可以用CListCtrl::InsertColumn()方法的另一个版本,你可以用下面的版本,来为控件创建列:
int
InsertColumn(int
nCol,
列的索引,必须要指定的;
LPCTSTR lpszColumnHeading,
在列的开始要显示的字符串,和LVCOLUMN::pszText成员相似;
LPCTSTR
lpszColumnHeading,
在列的开始要显示的字符串,和LVCOLUMN::pszText成员相似;
int
nFormat= LVCFMT_LEFT,用来指定lpszColumnHeading的水平对齐方式。默认为左对齐(LVCFMT_LEFT),居中为
int
nWidth=-1,以像素为单位来设定列的宽度,如果你不想指定它的大小,可设置为-1
int
nSubItem=-1);用来设定当前列子项的索引。
成员函数:
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); //设置扩展风格
插入数据 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”);//设置数据
设置为Report属性后,若要ListControl显示为列表状,则在Init函数中,添加:
ListView_SetExtendedListViewStyle(m_listctrl.m_hWnd,LVS_EX_GRIDLINES|LVS_EX_ONECLICKACTIVATE|LVS_EX_FULLROWSELECT);
int InsertItem( int nItem, LPCTSTR lpszItem ); 插入行
nItem:指明插入位置
lpszItem:为显示字符。
除
LVS_REPORT 风格外其他三种风格都只需要直接调用 InsertItem 就可以了,但如果使用报表风格就必须先设置列表控件中的列信息
。
int
InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int nFormat , int nWidth, int nSubItem); 插入列
iCol:为列的位置,从零开始
lpszColumnHeading:为显示的列名
nFormat:为显示对齐方式
nWidth:为显示宽度
nSubItem:为分配该列的列索引。
BOOL
SetItemText( int nItem, int nSubItem, LPTSTR lpszText );设置每列的显示字符
nItem:为行位置
nSubItem:为列位置
lpszText:为显示字符
下面的代码演示了如何设置多列并插入数据:
m_list.SetImageList(&m_listSmall,LVSIL_SMALL);//设置
ImageList
m_list.InsertColumn(0,"Col
1",LVCFMT_LEFT,300,0);//设置列
m_list.InsertColumn(1,"Col
2",LVCFMT_LEFT,300,1);
m_list.InsertColumn(2,"Col
3",LVCFMT_LEFT,300,2);
m_list.InsertItem(0,"Item
1_1");//插入行
m_list.SetItemText(0,1,"Item
1_2");//设置该行的不同列的显示字符
m_list.SetItemText(0,2,"Item
1_3")
总结:1.
ListCtrl 风格
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);
//设置扩展风格
--------------------------------------------------------------------------------
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<m_list.GetItemCount(); i )
{
if(
m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
{
str.Format(_T("第%d行的checkbox为选中状态"),
i);
AfxMessageBox(str);
}
}
CString
strIns;
strIns="delete
from tmpStatByGround";
m_pRs.CreateInstance(__uuidof(Recordset));
m_pRs->CursorLocation
= adUseClient;
m_pRs->Open((LPCTSTR)strIns,
vDispatch, adOpenKeyset,
adLockOptimistic,
adCmdUnknown);
--------------------------------------------------------------------------------
7.
得到listctrl中所有选中行的序号
方法一:
CString
str;
for(int
i=0; i<m_list.GetItemCount(); 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);
--------------------------------------------------------------------------------
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的 subitem 添加图标
注意:
首先要用 InsertItem() 插入一行的第一列, 然后才能用 SetItem 设置其他项
m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);
m_userlist.SetItem(..);
--------------------------------------------------------------------------------
18.
在CListCtrl显示文件,并根据文件类型来显示图标
网上找到的代码,自己试用并改正过,
share
步骤1:
设置 list 的图像列表为 系统图像列表
BOOL
SetSystemImageList( CListCtrl & list )
{
HIMAGELIST
himlSmall;
HIMAGELIST
himlLarge;
SHFILEINFO
sfi;
char
cSysDir[MAX_PATH];
CString
strBuf;
memset(cSysDir,
0, MAX_PATH);
GetWindowsDirectory(cSysDir,
MAX_PATH);
strBuf
= cSysDir ;
//
SHGetFileInfo:
//
If uFlags contains SHGFI_SYSICONINDEX, the return value is a handle to
//
an image list that contains the large icon images.
//
If SHGFI_SMALLICON is included with SHGFI_SYSICONINDEX, the return value
//
is the handle to an image list that contains the small icon images.
//
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(list.m_hWnd,
LVM_SETIMAGELIST,
(WPARAM)LVSIL_SMALL,
(LPARAM)himlSmall);
::SendMessage(list.m_hWnd,
LVM_SETIMAGELIST,
(WPARAM)LVSIL_NORMAL,
(LPARAM)himlLarge);
}
return
TRUE;
}
步骤2:
给列表添加指定的文件, 同时获得该文件的的图标索引, 给 list 添加图标
int
GetIconIndex(LPCTSTR lpszPath, BOOL bIsDir, BOOL bSelected) ; // 向前声明
void
AddFiles(CListCtrl & list, LPCTSTR lpszFileName, BOOL bAddToDocument)
{
int
nIcon = GetIconIndex(lpszFileName, FALSE, TRUE);
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 = list.GetItemCount();
//list.InsertItem(nItem,
strFileName, nIcon);
//list.SetItemText(nItem,
1, strSize);
//
//
此处可以根据实际需要修改代码
//
}
--------------------------------------------------------------------------------
19.
listctrl内容进行大数据量更新时,避免闪烁
m_list.SetRedraw(FALSE);
//更新内容
m_list.SetRedraw(TRUE);
m_list.Invalidate();
m_list.UpdateWindow();
20.
清除 ListCtrl 以重新初始化:
//
删除所有行
m_ctrllist.DeleteAllItems()
;
//
删除所有列
int
iColCount = m_ctrllist.GetHeaderCtrl()->GetItemCount() ;
//
方法 1
//
原理: 删除第一列后, 其他列向前移动
while(
m_ctrllist.DeleteColumn(0) ) ;
//
方法 2
for
(int i=0; i < iColCount ; i )
{
m_ctrllist.DeleteColumn(0);
}
//
方法 3
for
(int i=iColCount-1; i >= 0; i-- )
{
m_ctrllist.DeleteColumn(
i );
}
Icons: 控件显示项的列表,使用32*32(像素)大小的icons
Small
Icons:和剩下的两项相似的想法,它使用16*16(像素)大小的图标来显示一个单一的列表项
List:这种列表,使用small icons,也是组织列;这种情况下,在第二列填充之前必须填充第一列
Report:安排项的目的是提供列表开发者的信息
(1)
创建List Control
法1:列表初始化:
添加变量m_list .create(WS_CHILD|WS_VISIBLE,CRect(10,10,320,280),this,0x285;
创建控件的时候,增加LVS_ICON LVS_SMALLICON
LVS_REPORT LVS_REPORT等
除了常规的几种风格外,Win32类库为ListCtrl提供了扩展风格,提供了一个扩展风格,调用CListCtrl::SetExtendStyle()方法,它的语法为:
DWORD SetExtendedStyle(DWORD dwNewStyle);
LVS_ALIGNLEFT 显示格式是大图标或小图标时,标签放在图标的左边
LVS_ALIGNTOP 显示格式是大图标或小图标时,标题放在图标的上边
LVS_AUTOARRANGE 显示格式是大图标或小图标时,自动排列控件中的列表项
LVS_EDITLABELS 用户可以修改标签文本
LVS_ICON 指定大图标显示格式
LVS_LIST 指定列表显示格式
LVS_NOCOLUMNHEADER 在报表格式中不显示列的表头
LVS_NOLABELWRAP 显示格式是大图标时,使标签文本单行显示。默认是多行显示
LVS_NOSCROLL 列表视图控件无滚动条,此风格不能与LVS_LIST或LVS_REPORT组合使用
LVS_NOSORTHEADER 报表格式的列表视图控件的表头不能作为排序按钮使用
LVS_OWNERDRAWFIXED 由控件的拥有者负责绘制表项
LVS_REPORT 指定报表显示格式
LVS_SHAREIMAGELISTS 使列表视图共享图像序列
LVS_SHOWSELALWAYS 即使控件失去输入焦点,仍显示出项的选择状态
LVS_SINGLESEL 指定只能有一个列表项被选中。默认时可以多项选择
LVS_SMALLICON 指定小图标显示格式
LVS_SORTASCENDING 按升序排列列表项
LVS_SORTDESCENDING 按降序排列列表项
添加项(单元项):
结构体: typedefstruct
{
UINT mask;用来指定你想给当前项设置的类型。
int
iItem;指定改变项的索引,第一个item应该为0,第二个item为1等等。
int
iSubItem;当前值的的子项,如果当前项是主导项,iSumItem应该存储从0开始的数组
UINT state;
UINT stateMask;
LPTSTR pszText;
要显示项的字符串,你可以通过cchTextMask指定文本的长度
int cchTextMax;
int iImage;
LPARAM lParam;
} LVITEM,*LPLVITEM;
lvItem.mask=
LVIF_TEXT;
lvItem.iItem=0;
lvItem.iSubItem=0;
lvItem.pszText=
strNumber;m_list.InsertItem(&lvItem);
LVITEM结构体的值将决定新项的功能。例如,一旦增加了一个项,你可能想要准备删除前面的项、剪切和粘贴操作,在这种情况下,你应该将设置为LVIS_CUT;如果你想实现拖放操作,你可以设置LVIS_DROPHILIGHTED;如果想让项获得焦点,设置LVIS_FOCUSED;包含LVIS_SELECTED属性的情况下可以被选中
创建一个ListCtrl的列,
你可以使用CListCtrl::InsertColumn()方法,它的一种声明为:
int InsertColumn(int nCol, const LVCOLUMN* pColumn);
nCol:将要创建列的索引
pColumn:指向LVCOLUMN结构体指针,结构体定义如下:
typedefstruct
_LVCOLUMN {
UINT mask;用来指定你想要的列的属性
int
fmt;格式化列的文本(默认值LVCFMT_LEFT),居中(LVCFMT_CENTER),或者右对齐(LVCFMT_RIGHT)
int
cx;cx 用来指定列文本的宽度
LPTSTR pszText;pszText 是将要显示的列的字符串
int
cchTextMax;
int
iSubItem;
} LVCOLUMN, FAR*LPLVCOLUMN;
LVCOLUMN
lvColumn;
int
nCol; 例如
lvColumn.mask=
LVCF_FMT| LVCF_TEXT|
LVCF_WIDTH;
lvColumn.fmt=
LVCFMT_LEFT;
lvColumn.cx=120;
lvColumn.pszText=
TEXT("Full
Name");
nCol=
m_StoreItems.InsertColumn(0,&lvColumn);
你也可以用CListCtrl::InsertColumn()方法的另一个版本,你可以用下面的版本,来为控件创建列:
int
InsertColumn(int
nCol,
列的索引,必须要指定的;
LPCTSTR lpszColumnHeading,
在列的开始要显示的字符串,和LVCOLUMN::pszText成员相似;
LPCTSTR
lpszColumnHeading,
在列的开始要显示的字符串,和LVCOLUMN::pszText成员相似;
int
nFormat= LVCFMT_LEFT,用来指定lpszColumnHeading的水平对齐方式。默认为左对齐(LVCFMT_LEFT),居中为
int
nWidth=-1,以像素为单位来设定列的宽度,如果你不想指定它的大小,可设置为-1
int
nSubItem=-1);用来设定当前列子项的索引。
int InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int nFormat , int nWidth, int nSubItem)插入列。 nCol为列的位置,从零开始,lpszColumnHeading为显示的列名,nFormat为显示对齐方式, nWidth为显示宽度,nSubItem为分配给该列的列索引。
成员函数:
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); //设置扩展风格
插入数据 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”);//设置数据
设置为Report属性后,若要ListControl显示为列表状,则在Init函数中,添加:
ListView_SetExtendedListViewStyle(m_listctrl.m_hWnd,LVS_EX_GRIDLINES|LVS_EX_ONECLICKACTIVATE|LVS_EX_FULLROWSELECT);
int InsertItem( int nItem, LPCTSTR lpszItem ); 插入行
nItem:指明插入位置
lpszItem:为显示字符。
除
LVS_REPORT 风格外其他三种风格都只需要直接调用 InsertItem 就可以了,但如果使用报表风格就必须先设置列表控件中的列信息
。
int
InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int nFormat , int nWidth, int nSubItem); 插入列
iCol:为列的位置,从零开始
lpszColumnHeading:为显示的列名
nFormat:为显示对齐方式
nWidth:为显示宽度
nSubItem:为分配该列的列索引。
BOOL
SetItemText( int nItem, int nSubItem, LPTSTR lpszText );设置每列的显示字符
nItem:为行位置
nSubItem:为列位置
lpszText:为显示字符
下面的代码演示了如何设置多列并插入数据:
m_list.SetImageList(&m_listSmall,LVSIL_SMALL);//设置
ImageList
m_list.InsertColumn(0,"Col
1",LVCFMT_LEFT,300,0);//设置列
m_list.InsertColumn(1,"Col
2",LVCFMT_LEFT,300,1);
m_list.InsertColumn(2,"Col
3",LVCFMT_LEFT,300,2);
m_list.InsertItem(0,"Item
1_1");//插入行
m_list.SetItemText(0,1,"Item
1_2");//设置该行的不同列的显示字符
m_list.SetItemText(0,2,"Item
1_3")
总结:1.
ListCtrl 风格
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);
//设置扩展风格
--------------------------------------------------------------------------------
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<m_list.GetItemCount(); i )
{
if(
m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
{
str.Format(_T("第%d行的checkbox为选中状态"),
i);
AfxMessageBox(str);
}
}
CString
strIns;
strIns="delete
from tmpStatByGround";
m_pRs.CreateInstance(__uuidof(Recordset));
m_pRs->CursorLocation
= adUseClient;
m_pRs->Open((LPCTSTR)strIns,
vDispatch, adOpenKeyset,
adLockOptimistic,
adCmdUnknown);
--------------------------------------------------------------------------------
7.
得到listctrl中所有选中行的序号
方法一:
CString
str;
for(int
i=0; i<m_list.GetItemCount(); 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);
--------------------------------------------------------------------------------
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的 subitem 添加图标
注意:
首先要用 InsertItem() 插入一行的第一列, 然后才能用 SetItem 设置其他项
m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);
m_userlist.SetItem(..);
--------------------------------------------------------------------------------
18.
在CListCtrl显示文件,并根据文件类型来显示图标
网上找到的代码,自己试用并改正过,
share
步骤1:
设置 list 的图像列表为 系统图像列表
BOOL
SetSystemImageList( CListCtrl & list )
{
HIMAGELIST
himlSmall;
HIMAGELIST
himlLarge;
SHFILEINFO
sfi;
char
cSysDir[MAX_PATH];
CString
strBuf;
memset(cSysDir,
0, MAX_PATH);
GetWindowsDirectory(cSysDir,
MAX_PATH);
strBuf
= cSysDir ;
//
SHGetFileInfo:
//
If uFlags contains SHGFI_SYSICONINDEX, the return value is a handle to
//
an image list that contains the large icon images.
//
If SHGFI_SMALLICON is included with SHGFI_SYSICONINDEX, the return value
//
is the handle to an image list that contains the small icon images.
//
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(list.m_hWnd,
LVM_SETIMAGELIST,
(WPARAM)LVSIL_SMALL,
(LPARAM)himlSmall);
::SendMessage(list.m_hWnd,
LVM_SETIMAGELIST,
(WPARAM)LVSIL_NORMAL,
(LPARAM)himlLarge);
}
return
TRUE;
}
步骤2:
给列表添加指定的文件, 同时获得该文件的的图标索引, 给 list 添加图标
int
GetIconIndex(LPCTSTR lpszPath, BOOL bIsDir, BOOL bSelected) ; // 向前声明
void
AddFiles(CListCtrl & list, LPCTSTR lpszFileName, BOOL bAddToDocument)
{
int
nIcon = GetIconIndex(lpszFileName, FALSE, TRUE);
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 = list.GetItemCount();
//list.InsertItem(nItem,
strFileName, nIcon);
//list.SetItemText(nItem,
1, strSize);
//
//
此处可以根据实际需要修改代码
//
}
--------------------------------------------------------------------------------
19.
listctrl内容进行大数据量更新时,避免闪烁
m_list.SetRedraw(FALSE);
//更新内容
m_list.SetRedraw(TRUE);
m_list.Invalidate();
m_list.UpdateWindow();
20.
清除 ListCtrl 以重新初始化:
//
删除所有行
m_ctrllist.DeleteAllItems()
;
//
删除所有列
int
iColCount = m_ctrllist.GetHeaderCtrl()->GetItemCount() ;
//
方法 1
//
原理: 删除第一列后, 其他列向前移动
while(
m_ctrllist.DeleteColumn(0) ) ;
//
方法 2
for
(int i=0; i < iColCount ; i )
{
m_ctrllist.DeleteColumn(0);
}
//
方法 3
for
(int i=iColCount-1; i >= 0; i-- )
{
m_ctrllist.DeleteColumn(
i );
}
相关文章推荐
- hdu 2828 Lamp 贪心 + 二分匹配
- UISearchBar(搜索框)的方法属性介绍
- HDU 1064Financial Management(高精度问题)
- 关于mysql函数GROUP_CONCAT
- Android自定义控件
- HTML+CSS画同心圆
- 微信公众号内支付(二)
- Sql Server中Float格式转换字符串varchar方法(转)
- 启用了不安全的HTTP方法
- CodeForces 656B
- LeetCode(24)-Balanced Binary Tree
- windows和Linux中进行文件传输
- 将单个文件上传到多机器工具
- LeetCode(24)-Balanced Binary Tree
- LeetCode(24)-Balanced Binary Tree
- Android Studio 设置项目Module编码,解决Android Studio项目运行时乱码问题
- 码农小汪剑指Offer之36-二叉树的深度 层次遍历 分而冶之
- 原型prototype与原型链__proto__
- hdu 3466 Proud Merchants 贪心+01背包
- 游戏开发创建游戏世界(8)