MFC中怎样使用ListCtrl

一、 概述

ListCtrl由四种风格的实现:

Icons,使用32*32大小的图标显示列表。

Small Icons,使用16*16大小的图标显示一个单一列的列表。

List,使用Small Icons,可有多列,第二列必须填充之前必须填充第一列,自上而下排序。

Report,编程者自定义的格式显示列表。

二、 ListCtrl介绍

创建一个“基于对话框”的MFC应用程序,命名为ListCtrl

1)创建ListCtrl

一般来说ListCtrl控件的创建都是直接拖拽工具箱中的控件完成的。如果要用代码实现,则应该在ListCtrlDlg.cpp中的OnInitDialog()函数中实现。一般对ListCtrl的属性的更改也应该在此函数中。

CListCtrl *lstCtrl = new CListCtrl;
lstCtrl->Create(WS_CHILD | WS_VISIBLE,CRect(1010320280), this0x285);

为了防止内存泄露,正确的做法是,在ListCtrlDlg.h头文件中添加变量m_ListCtrl,在OnInitDialognew,最后在析构函数中Delete

2ListCtrl风格

ListCtrl的风格可以在ListView属性中更改。

1.Icon风格LVS_ICON

2.Small Icon风格:LVS_SMALLICON

3.List风格:LVS_LIST

4.Report风格:LVS_REPORT

3ListCtrl扩展风格

调用CListCtrl::SetExtendStyle()方法可以为ListCtrl设置扩展风格,语法为:

DWORD SetExtendedStyle(DWORD dwNewStyle);

参数值有:

LVS_EX_CHECKBOXES:左侧显示选择框(check box)

LVS_EX_FULLROWSELECT:这种风格允许Report View的整行来被选择而不是仅仅一项

LVS_EX_TRACKSELECT:当设置这种风格的时候,用户可以隔项选取

LVS_SINGLESEL:禁止用户一次选择多项

LVS_SHOWSELALWAYSListCtrl在失去焦点时,已选择的项仍处于选中状态

LVS_EX_GRIDLINES:显示网格

设置扩展风格,可以先创建一个DWORD变量,然后对变量赋值。如果想用多种风格,可以用|操作。

注:listviewstyle请查阅msdn
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp

三、 创建一个ListCtrl

(1) 添加List的项

调用CListCtrl::InsertItem()方法来为List添加该有的项。

声明如下:int InsertItem(const LVITEM* pItem);

注:此方法适用于ListCtrl风格为List时,风格为Report则无法显示数据。

此方法需要用到一个LVITEM的指针,LVITEM为一个结构体,其中比较重要的参数有:

mask:用来指定你像个当前项设置的类型。

iItem:指定项的索引,第一个item应该为0,第二个item1等等

iSumItem:当前值的的子项,如果当前项是主导项,iSumItem应该存储从0开始的数组

pszText:要显示项的字符串

cchTextMask指定文本的长度

使用上述方法,为List添加一项:(m_StoreItemsListCtrl变量)

LVITEM lvItem;
lvItem.mask = LVIF_TEXT;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.pszText = _T("Sandra C. Anschwitz");
m_StoreItems.InsertItem(&lvItem);

但是我们平时经常用的InsertItem方法为:

int InsertItem(int nItem, LPCTSTR lpszItem);

四、 构建ListCtrl

如果选择ListCtrl的风格为Report,那么在添加项之前,要先创建列。

我们可以使用CListCtrl::InsertColumn()方法,

1)它的一种声明为:

int InsertColumn(int nCol, const LVCOLUMN* pColumn);

nCol:是要创建的列的索引

pColumn:是指向LVCOLUMN结构的一个指针

typedef struct _LVCOLUMN { 

    UINT mask; 

    int fmt; 

    int cx; 

    LPTSTR pszText; 

    int cchTextMax; 

    int iSubItem; 

    #if (_WIN32_IE >= 0x0300)

        int iImage;

        int iOrder;

    #endif

} LVCOLUMN, FAR *LPLVCOLUMN;

mask:     指定你创建的列的属性。

fmt:     格式化的文本。例如,你可以选择左对齐(默认值LVCFMT_LEFT),居中(LVCFMT_CENTER),右对齐。如果你想为这个值设置一个值,那么在初始化mask变量的时候增加LVCF_FMT属性。

cx:       用来指定列文本的宽度。如果未初始化,他的长度将被设定为刚好能显示文本的长度。除非你有特别好的理由省略它,一般要对其进行初始化。如果打算初始化此值,给mask增加LVCF_WIDTH属性。

pszText: 指定创建列的表头。除了第一列,此变量不是必须初始化的。要想初始化此变量,在mask增加LVCF_TEXT属性。

cchTextMax:指定表头的长度。

添加一列的代码:

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

(2) CListCtrl::InsertColumn()的另一种声明为

int InsertColumn(int nCol,LPCTSTR lpszColumnHeading,int nFormat = LVCFMT_LEFT,
int nWidth = -1,int nSubItem = -1);

nCol:列的索引。

lpszColumnHeading:表头标题显示的字符

nFormat:表头文字的对齐方式。默认为左对齐(LVCFMT_LEFT.

wWidth:以像素为单位设置列的宽度。

nSubItem:设置当前列子项的索引。-1时表示没有子项与此列相关。

InsertColumn()方法返回一个整形值来标识你增加的列。

然后通过调用CListCtrl::SetItemText()方法来为此列添加具体的字符串。

BOOL SetItemText(int nItem, int nSubItem, LPTSTR lpszText);

nItem:第几行

nSubItem:第几列

lpszText:字符串信息

//首先定义列,此处定义了三列

LVCOLUMN lvColumn;

lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;

lvColumn.fmt = LVCFMT_LEFT;

    lvColumn.cx = 120;

    lvColumn.pszText = TEXT("Full Name");

    m_StoreItems.InsertColumn(0, &lvColumn);

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;

    lvColumn.fmt = LVCFMT_LEFT;

    lvColumn.cx = 100;

    lvColumn.pszText = TEXT("Profession");

    m_StoreItems.InsertColumn(1, &lvColumn);

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;

    lvColumn.fmt = LVCFMT_LEFT;

    lvColumn.cx = 80;

    lvColumn.pszText = TEXT("Fav Sport");

    m_StoreItems.InsertColumn(2, &lvColumn);

    //然后添加一行

LVITEM lvItem;

    int nItem;

    lvItem.mask = LVIF_TEXT;

    lvItem.iItem = 0;

    lvItem.iSubItem = 0;

    lvItem.pszText = TEXT("Sandra C. Anschwitz");

    nItem = m_StoreItems.InsertItem(&lvItem);

    //添加此行的子项,与上边定义的列数相对应

m_StoreItems.SetItemText(nItem, 1, TEXT("Singer"));

    m_StoreItems.SetItemText(nItem, 2, TEXT("HandBall"));

五、 Views动态转换

首先通过GetWindowLong()获得当前控件的风格,在将返回值与LVS_TYOEMASK的反进行&操作,这样返回值就会被清零。然后将返回值与要改变的风格进行|操作,最后使用SetWindowLong()重新设置控件风格即可。

LONG mListStyle = ::GetWindowLong(m_List.m_hWnd, GWL_STYLE);

mListStyle &= ~LVS_TYPEMASK;

mListStyle |= LVS_ICON;

::SetWindowLong(m_List.m_hWnd, GWL_STYLE, mListStyle);

六、 在表头上添加图片

如果想在表头上添加一副位图,你要先声明一个CImageList变量,并初始化。然后调用CListCtrl::SetImageList()方法,并为之传参。如果你这么做,并且你使用的是LVCOLUMN指针作为CListCtrl::InsertColumn()的参数,需要给mask参数添加LVCF_IMAGE的值,并为fmt添加LVCFMT_IMAGE的值。

实现代码:

LVCOLUMN lvColumn;

CImageList *ImgHeaders = new CImageList;

//参数16,16指明了在IDI_UPIDI_LOSANGE中使用哪一个像素的图像。也可以改为32,32

ImgHeaders->Create(16, 16, ILC_MASK, 1, 1);

//将图标加载到ImageList

ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_UP));

ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_LOSANGE));

//使用SetImageListImageList赋值给ListCtrl,这样ListCtrl就可以使用ImageList中的图标

m_List.SetImageList(ImgHeaders, LVSIL_SMALL);

//如果想要表头加载图标,就必须为maskfmt赋值参数,并通过iImage来指定使用ImageList中的哪个图标

lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_IMAGE;

lvColumn.fmt = LVCFMT_LEFT | LVCFMT_IMAGE;

lvColumn.cx = 120;

//参数指明使用第一个图标,这里的顺序与上边Add的顺序一样

lvColumn.pszText = "Full Name";

lvColumn.iImage = 0;

m_List.InsertColumn(0, &lvColumn);

//不添加图标则不用赋值

lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;

lvColumn.fmt = LVCFMT_LEFT;

lvColumn.cx = 100;

lvColumn.pszText = "Profession";

m_List.InsertColumn(1, &lvColumn);

lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_IMAGE;

lvColumn.fmt = LVCFMT_LEFT | LVCFMT_IMAGE;

lvColumn.iImage = 1;

lvColumn.cx = 80;

lvColumn.pszText = "Fav Sport";

m_List.InsertColumn(2, &lvColumn);

lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;

lvColumn.fmt = LVCFMT_LEFT;

lvColumn.cx = 75;

lvColumn.pszText = "Hobby";

m_List.InsertColumn(3, &lvColumn);

七、 在每一项上显示图片

与上面再表头显示图片类似。在第一列的最左端显示图片。

代码(接6的代码使用)

LVITEM lvItem;
int nItem;

lvItem.mask = LVIF_TEXT;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.iImage = 0;
lvItem.pszText = _T(你好);
nItem = m_StoreItems.InsertItem(&lvItem);

m_StoreItems.SetItemText(nItem, 1_T(2));
m_StoreItems.SetItemText(nItem, 2_T(3));
m_StoreItems.SetItemText(nItem, 3_T(4));

八、 获取单击的行号和列号

找到ListCtrl控件的属性,添加onNMClickList1单击事件响应函数。

函数原型:void OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)

在函数中添加如下代码:

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

//如果单击的不是空白或分割线,就执行

if(pNMListView->iItem != -1) 

{

CString strtemp("11");

//获取行号和列号

    strtemp.Format(_T(“第%d%d”),pNMListView->iItem,pNMListView->iSubItem);

    ::AfxMessageBox(strtemp);

}

九、 删除某一行

接上边8的代码:

m_List->DeleteItem(pNMListView->iItem);//传递参数为行号

十、 添加位图

ListCtrl追加位图图标

加载位图
CBitmap bmap;
bmap.LoadBitmap(IDB_BITMAP_LIST_ICON);
m_pImageList = new CImageList;
m_pImageList->Create( 20, 20, ILC_COLOR24, 11, 0 );
m_pImageList->Add( &bmap, (COLORREF)0 );
bmap.DeleteObject();
list.SetImageList( m_pImageList, LVSIL_SMALL );

//设置属性

//report
long style = GetWindowLong(lc.m_hWnd,GWL_STYLE);
style |= (LVS_REPORT|LVS_SINGLESEL| LVS_ALIGNTOP |LVS_SHOWSELALWAYS );
SetWindowLong(lc.m_hWnd,GWL_STYLE,style);

//扩展属性

//网格化----行全选----列可以加位图
lc.SetExtendedStyle( LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT|LVS_EX_SUBITEMIMAGES );

lc.InsertItem( iRow,strItemText,getImage());
//iColum列加位图  
lc.SetItem( iRow,iColum,LVIF_IMAGE,_T(""),ICON_TIMER,0,0,0,0);

你可能感兴趣的:(MFC中怎样使用ListCtrl)