在ListCttrl控件(Report风格)的使用上,有时需要向子列中插入图标,例如要制作一个下载软件,我们计划在控件的第一列用图标的形式显示下载状态:排队、下载中、出错等等,第二列计划用图标显示下载文件类型,要做出这样的效果,就必须使用CListCtrl的SetItem(八个参数)方法,由于我这台电脑上没有MSDN所以这八个参数具体都是什么意思我暂时不清楚,在这只介绍下跟我们的操作关系密切的几个参数。
SetItem()从左向右数第一个参数(从1起计数)表示操作行的行号,这个行号从0计数,最好这个参数设置为InsertItem()的返回值,也就是说应该先用InsertItem()插入一个空行,之后用SetItemText()具体设置插入行每一列的值。SetItem()的第二个参数表示即将操作的列号,也就是我们打算将图标插入到第几列中,该行号从0计数。SetItem()的第五个参数表示图标在CImageList对象(该对象已经通过SetImageList(&ImageList, LVSIL_SMALL)附属至CListCtrl控件)中的序数,该序数从0计数,顺便说一句,准备附属到CListCtrl控件的CImageList对象必须是全局性的,比如可以是类的成员,否则就算其他操作都都正确也看不到图标。
举个例子我们使用的CListCtrl控件的控制对象为m_List,m_List中已经添加了三个列,IDX是InsertItem()的返回值,表示刚刚插入的新行,附属到m_List的CImageList对象中有5个图标,我们通过m_List.SetItem(IDX, 0, LVIF_IMAGE, NULL, 1, 0, 0, 0);之后,就把CImageList对象中的第1个图标插在了第一列的前部(原先第一列的文字还在),之后接着通过m_List.SetItem(IDX, 2, LVIF_IMAGE, NULL, 0, 0, 0, 0);就把CImageList对象中的第0个图标插在了第二列的前部(原先的文字还在)。可以看到如下实例图:
有一点值得说明,如果只在子列中插入了图标而没有给主列(第一列)插入任何图标,则默认第一列将插入与同一行最后一次给子列插入图标。 还有重要的一点,如果想在子列插入图标,首先必须使ListCtrl控件具备LVS_EX_SUBITEMIMAGES风格,例如我们可以通过m_List.SetExtendedStyle(m_List.GetExtendedStyle()|LVS_EX_SUBITEMIMAGES);给控件附加该风格。一.CListCtrl在第一列添加图标
CListCtrl可以很方便的在第一列添加图标, 并且在不同的显示方式(1:LVS_ICON: 为每个item显示大图标;2:LVS_SMALLICON: 为每个item显示小图标;3: LVS_LIST: 显示一列带有小图标的item;4:LVS_REPORT: 显示item详细资料)下, 都可以把第一列的图标显示出来.。
具体方法为:
1.在Dialog的头文件中声明CListCtrl控件和CImageList类变量
CListCtrl m_lstEnumDev; |
2.在Dialog的OnInitDialog()中
/*******设置列表表头内容和宽度*****/ m_SmallIcon.Create(16,16, 1, 10, 4); m_LargeIcon.Create(32,32, 1, 10, 4); m_SmallIcon.SetBkColor(RGB(255, 255, 255)); //需要设置背景色为白色,否则图标镂空的地方都是黑色,且图标有黑边框 m_LargeIcon.SetBkColor(RGB(255, 255, 255)); //需要设置背景色为白色,否则图标镂空的地方都是黑色,且图标有黑边框 m_SmallIcon.Add(AfxGetApp()->LoadIcon(IDI_ICON_SMALL));m_LargeIcon.Add(AfxGetApp()->LoadIcon(IDI_ICON_LARGE)); m_lstEnumDev.SetImageList(&m_LargeIcon,LVSIL_NORMAL); m_lstEnumDev.SetImageList(&m_SmallIcon,LVSIL_SMALL);
ShowListInfo(); |
3.在ShowListInfo()中显示列表中的信息
for (int i=0;i<iItemNum;i++) |
实现以上3步,就可以显示带图标的文本项了。
4.可在Dialog的头文件中声明CComboBox m_cmbViewType变量,控制不同的显示方式。
/******初始化下拉列表*****/ |
5.相应CComboBox的CBN_SELCHANGE消息,实现不同的显示方式
int nSel = m_cmbViewType.GetCurSel(); |
经过以上5步,即可实现,在不同的显示方式下,使列表的第一列显示(相同或不同的)图标。
二.CListCtrl非第一列添加图标
如果除了要使第一列显示图标外,还要使也其他列显示。只需要按照第一列那样声明一个LV_ITEM lvitem;
lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; |
如果只让非第一列显示图标,就会出现一个问题——CImageList是和CListCtrl的第一列绑定的,这个第一列是逻辑上的。
那可不可以使(视图上的)非第一列变成(逻辑上的)的第一列呢?
我的实现思想是:显示在视图上的非第一列其实是CListCtrl的逻辑上的第一列,即:m_lstEnumDev.InsertColumn(0,"名称");这个" 0" 其实就是逻辑上的第一列。
那该怎么实现呢?
我的实现思想是:使第一列和其他的某列交换位置。调用了CListCtrl 的GetHeaderCtrl()方法,通过表头控件CHeaderCtrl的SetOrderArray设置(视图上的)显示顺序。
/*******第一和最后一列交换位置***/ pmyHeaderCtrl->SetOrderArray(nCount, pnOrder); |