您的位置:首页 > 其它

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);用来设定当前列子项的索引。

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 );

}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: