列表视图控件
图标风格
CListCtrl类里要了解的函数
SetImageList为列表控件关联一个图像列表
InsertItem插入一项
GetSelectionMark获取选中项的索引
GetItemText根据项索引获取项文本内容
首先往工程里引入七个图标,接着在对话框里添加一个列表视图控件,然后为控件关联一个变量CListCtrl,再往对话框类添加一个变量CImageList m_ImageList;
在对话框类的初始化函数中添加以下代码:
m_ImageList.Create(32,32,ILC_COLOR24|ILC_MASK,1,0);
for(int i=0;i<7;i++)
m_ImageList.Add(LoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_ICON1+i)));
m_ListCtrl.SetImageList(&m_ImageList,LVSIL_NORMAL);
for(i=0;i<7;i++)
{
CString str;
str.Format("小明%d",i);
m_ListCtrl.InsertItem(i,str,i);
}
运行效果:
获取选中项内容(单击一个按钮,弹出消息提示)按钮消息处理函数代码:
int Sel=m_ListCtrl.GetSelectionMark();
CString str;
str=m_ListCtrl.GetItemText(Sel,0);
MessageBox(str);
报告风格
SetExtendedStyle设置列表控件扩展风格,该函数只有一个参数,关于该参数的解释,没找到中文的,只能先用英文替着了(msdn)
(PS:LVS_EX_CHECKBOXES设置项具有有核记风格,GetCheck可以用于判断一个项有无核记
LVS_EX_TRACKSELECT设置项具有热点风格,GetHotItem可获取当前鼠标热点项)
)
InsertColumn插入一列
InsertItem插入一行
SetItemText根据行列,设置一项数据
把列表控件改成“报告”风格
然后在初始化函数里添加以下语句:
//设置行列线和可以整行选中风格
m_ListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);
//插入三列
m_ListCtrl.InsertColumn(0,"商品名称",LVCFMT_LEFT,100);
m_ListCtrl.InsertColumn(1,"买入价格:元",LVCFMT_LEFT,100);
m_ListCtrl.InsertColumn(2,"卖出价格:元",LVCFMT_LEFT,100);
//插入一行
m_ListCtrl.InsertItem(0,"洗衣粉",0);
m_ListCtrl.SetItemText(0,1,"10");//设置0列1行数据
m_ListCtrl.SetItemText(0,2,"15");
m_ListCtrl.InsertItem(1,"牙膏",1);
m_ListCtrl.SetItemText(1,1,"8");
m_ListCtrl.SetItemText(1,2,"12");
运行效果:
获取选中数据,可先用GetSelectionMark获取选中行,再用GetItemText获取具体内容,如果获取选中的商品名称:
int Sel=m_ListCtrl.GetSelectionMark();
char str[52];
m_ListCtrl.GetItemText(Sel,0,str,52);
MessageBox(str);
设置列表视图控件项行高及字体大小
过程跟设置菜单栏项高及字体大小一样,处理WM_MEASUREITEM和WM_DRAWITEM消息,不过是处理对话框里这两个消息,前面说过了,子窗口是接不到这两个消息的,所以不要给从CListCtrl派生下来的类添加这两个消息处理函数,处理父窗口的消息就行了,如果要子窗口接收到这两个消息,需要消息反射,这里就直接处理父窗口的消息了,关于用消息反射的方法将在后面介绍。因为是采用WM_DRAWITEM消息的方式自绘,所以列表框得改成"报告"风格,(剩下三种风格不支持).
(PS:后面才发现,直接重载父类的方法也可以,DrawItem方法,是个虚函数,而不必响应父窗口WM_DRAWITEM消息,再调用DrawItem函数,我只在自绘按钮控件中用过这个方法,因为其它的不能在界面重载这个方法,以为没有,也没怎么注意)
首先从CListCtrl类派生出子类CNewListCtrl,然后给CNewListCtrl类添加一个函数:
void NewListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
该函数代码如下:
void CNewListCtrl::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your message handler code here and/or call default
// TODO: Add your code to draw the specified item
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
CRect rect=lpDrawItemStruct->rcItem;
dc.FillSolidRect(rect,RGB(38,255,147));
CHeaderCtrl* pHeaderCtrl =GetHeaderCtrl();
int colCount = pHeaderCtrl->GetItemCount();//获取列数量
int line=lpDrawItemStruct->itemID;
dc.SetTextColor(RGB(255,62,62));
CFont Font;
Font.CreatePointFont(125,"宋体");//创建字体
dc.SelectObject(&Font);
for(int col=0;col
{
CString str=GetItemText(line,col);//获取项文本
int colWidth=GetColumnWidth(col);//获取列宽度
dc.DrawText(str,rect,DT_VCENTER|DT_LEFT|DT_SINGLELINE);
rect.left+=colWidth;
}
dc.Detach();
}
给父窗口(对话框)添加WM_MEASUREITEM和WM_DRAWITEM消息处理函数,两个函数代码分别如下:
void CSixthDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
// TODO: Add your message handler code here and/or call default
if(lpMeasureItemStruct->CtlType==ODT_LISTVIEW)
lpMeasureItemStruct->itemHeight=25;//设置行高
else
CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
void CSeventhDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if(lpDrawItemStruct->CtlType==ODT_LISTVIEW)
m_ListCtrl.DrawItem(lpDrawItemStruct);//m_ListCtrl为列表控件关联的变量
else
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
接下来给对话框添加一个列表控件,设置风格为“报告”,勾上“所有者绘制固定"并关联变量m_ListCtrl,类型CNewListCtrl(记得包含头文件)。
对话框初始化函数代码如下:
m_ListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES);
//插入三列
m_ListCtrl.InsertColumn(0,"商品名称",LVCFMT_LEFT,100);
m_ListCtrl.InsertColumn(1,"买入价格:元",LVCFMT_LEFT,100);
m_ListCtrl.InsertColumn(2,"卖出价格:元",LVCFMT_LEFT,100);
//插入一行
m_ListCtrl.InsertItem(0,"洗衣粉",0);
m_ListCtrl.SetItemText(0,1,"10");//设置0列1行数据
m_ListCtrl.SetItemText(0,2,"15");
m_ListCtrl.InsertItem(1,"牙膏",1);
m_ListCtrl.SetItemText(1,1,"8");
m_ListCtrl.SetItemText(1,2,"12");
运行效果:
上面依然只是简单处理了一下项状态,甚至连选中的状态都没有处理,如果需要处理的话,可自行参考PDRAWITEMSTRUCT结构里的itemState变量解释
如:if(lpDrawItemStruct->itemState&ODS_SELECTED) //如果项被选中