MFC_ListView
2014-03-15 16:46
549 查看
1. 获取当前选择行
2. 添加图片列
3. 排序
4. 设置行高(待更好方法)
5. 固定列宽 (重载OnNotify函数)
1. 获取CListCtrl控件当前选择行的某一列数据
2. 添加图片列
//设置
CListCtrl& wndList = GetListCtrl();
DWORD dwStyle = wndList.GetExtendedStyle();
dwStyle = dwStyle|LVS_EX_FULLROWSELECT|LVS_NOSCROLL|LVS_EX_SUBITEMIMAGES;// LVS_EX_SUBITEMIMAGES
wndList.SetExtendedStyle(dwStyle); //设置扩展风格
wndList.SetImageList(&m_ImagesList, LVSIL_SMALL);//m_ImagesList 为CImageList*
wndList.InsertColumn(0, _T("From"), LVCFMT_LEFT, 100);
wndList.InsertColumn(1, _T("Subject"), LVCFMT_LEFT, 200);
//添加
//当有 LVS_SORTASCENDING风格时, 插入某行时, insertItem返回值为插入到第j行
int j = wndList.InsertItem(1, _T("tom"), 0);
wndList.SetItem(j, 2, LVIF_TEXT|LVIF_IMAGE, NULL, 3,0, 0, 0);
//3表示图象索引,2表示要插入的列
3. 排序
点击列的标题进行排序。
(上传MyListView.h中类CMyListView即实现了此功能, 但有所改变, 可调用 CallSort(int nSortCol, BOOL dftOrder = FALSE) 进行排序)
在添加该消息响应函数前,先要定义实现排序的回调函数。 有些应用中, 第一列是图像帧号, 按自然数排列,其他按字串排列,两个比较的回调函数。
步骤:
a. 在MyListView.h中声明两个静态的回调函数:
b. 通过向导(或手动)为事件LVN_COLUMNCLICK添加消息响应函数 OnColumnClick(). 点击表头。
1. .h中声明 afx_msg void OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult);
.cpp中
并实现:
4. 设置行高(待更好的方法)
这里行高变为20. 适应“图片”大小
5. 固定列宽
.h 类中添加重载函数和成员变量/函数如下:
.cpp中
2. 添加图片列
3. 排序
4. 设置行高(待更好方法)
5. 固定列宽 (重载OnNotify函数)
1. 获取CListCtrl控件当前选择行的某一列数据
CListCtrl& rList = GetListCtrl(); POSITION pos = rList.GetFirstSelectedItemPosition(); //while(pos!=NULL)//选中多个 if(pos!=NULL))//只选1个 { int nItem = rList.GetNextSelectedItem(pos); CString st = rList.GetItemText(nItem, 0); AfxMessageBox(st); }
2. 添加图片列
//设置
CListCtrl& wndList = GetListCtrl();
DWORD dwStyle = wndList.GetExtendedStyle();
dwStyle = dwStyle|LVS_EX_FULLROWSELECT|LVS_NOSCROLL|LVS_EX_SUBITEMIMAGES;// LVS_EX_SUBITEMIMAGES
wndList.SetExtendedStyle(dwStyle); //设置扩展风格
wndList.SetImageList(&m_ImagesList, LVSIL_SMALL);//m_ImagesList 为CImageList*
wndList.InsertColumn(0, _T("From"), LVCFMT_LEFT, 100);
wndList.InsertColumn(1, _T("Subject"), LVCFMT_LEFT, 200);
//添加
//当有 LVS_SORTASCENDING风格时, 插入某行时, insertItem返回值为插入到第j行
int j = wndList.InsertItem(1, _T("tom"), 0);
wndList.SetItem(j, 2, LVIF_TEXT|LVIF_IMAGE, NULL, 3,0, 0, 0);
//3表示图象索引,2表示要插入的列
3. 排序
点击列的标题进行排序。
(上传MyListView.h中类CMyListView即实现了此功能, 但有所改变, 可调用 CallSort(int nSortCol, BOOL dftOrder = FALSE) 进行排序)
在添加该消息响应函数前,先要定义实现排序的回调函数。 有些应用中, 第一列是图像帧号, 按自然数排列,其他按字串排列,两个比较的回调函数。
步骤:
a. 在MyListView.h中声明两个静态的回调函数:
static int CALLBACK ListViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);//按字串排序 static int CALLBACK ListViewCompareIntFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);//按自然数排序在.cpp中实现:
int CALLBACK ListViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { //得到排序方式 int *pisorder = (int*)lParamSort; //得到两个列的排序信息 TCHAR *sz1 = (TCHAR*)lParam1; TCHAR *sz2 = (TCHAR*)lParam2;//得到两个列的排序信息 //比较, 若为降序, 则将结果 * -1 if(*pisortorder == LVS_SORTASCENDING) return lstrcmp(sz1, sz2); else return lstrcmp(sz1, sz2) * (-1); } int CALLBACK CMyListView::ListViewCompareIntFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { int *pisortorder = (int*)lParamSort;//得到排序方式 TCHAR *sz1 = (TCHAR*)lParam1; TCHAR *sz2 = (TCHAR*)lParam2;//得到两个列的排序信息 int n1 = _ttoi(sz1);//? 不用单独提出int int n2 = _ttoi(sz2); if(*pisortorder == LVS_SORTASCENDING) { if(n1 - n2 > 0) return 1; else if(n1 - n2 == 0) return 0; else return -1; } else { if(n1 - n2 > 0) return -1; else if(n1 - n2 == 0) return 0; else return 1; } }
b. 通过向导(或手动)为事件LVN_COLUMNCLICK添加消息响应函数 OnColumnClick(). 点击表头。
1. .h中声明 afx_msg void OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult);
.cpp中
IMPLEMENT_DYNCREATE(CMyListView, CListView) BEGIN_MESSAGE_MAP(CMyListView, CListView) ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick) END_MESSAGE_MAP()
并实现:
void CMyListView::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult) { static int ncurSortCol = -1;//保存当前的排序列 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; CListCtrl* rList = &GetListCtrl(); LONG ws = GetWindowLong(rList->m_hWnd, GWL_STYLE); int nSortOrder;//排序的方式, 升序降序 //若点击列与当前排序列不同, 则改变排序列, 并将排序方式定为增序(降序也可) //若相同, 则更改排序方式。 if(ncurSortCol == pNMListView->iSubItem) { if(ws & LVS_SORTASCENDING) { ws ^= LVS_SORTASCENDING; nSortOrder = LVS_SORTDESCENDING; } else { ws ^= LVS_SORTDESCENDING; nSortOrder = LVS_SORTASCENDING; } } else { if(ws & LVS_SORTASCENDING) { //ws ^= LVS_SORTASCENDING;//文中没有,但是否需要? nSortOrder = LVS_SORTDESCENDING; ncurSortCol = pNMListView->iSubItem; } else { //ws ^= LVS_SORTDESCENDING; nSortOrder = LVS_SORTASCENDING; ncurSortCol = pNMListView->iSubItem; } } //将当前的排序信息保存在窗口Style中,供以后使用。 ws |= nSortOrder; SetWindowLong(rList->m_hWnd, GWL_STYLE, ws);//将当前的排序信息保存在窗口Style中 //将各item的lparam用新排序列的内容替换 LVITEM li; li.mask = LVIF_PARAM | LVIF_TEXT; TCHAR szItemText[1024]; for(int i=0; i<rList->GetItemCount(); i++) { li.iItem = i; li.iSubItem = ncurSortCol; li.cchTextMax = 1024; li.pszText = szItemText; rList->GetItem(&li); TCHAR* szlparam = (TCHAR*)li.lParam; //删除以前的信息, 释放空间 //添加list item时应注意将lParam初始化NULL. if(szlparam != NULL) delete szlparam; //复制当前列的szitemtext到item的lparam中 szlparam = new TCHAR[lstrlen(szItemText)+1]; lstrcpy(szlparam, szItemText); rList->SetItemData(i, DWORD(szlparam)); } //开始排序 if(ncurSortCol == 0) //第一排按整数排序 { rList->SortItems(ListViewCompareIntFunc, (LPARAM)(&nSortOrder)); } else { rList->SortItems(ListViewCompareFunc, (LPARAM)(&nSortOrder)); } *pResult = 0; }
4. 设置行高(待更好的方法)
这里行高变为20. 适应“图片”大小
m_ImagesList.Create(5, 20, ILC_COLOR32, 5, 5); GetListCtrl().SetImageList(&m_ImagesList, LVSIL_SMALL);
5. 固定列宽
.h 类中添加重载函数和成员变量/函数如下:
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult); std::vector<int> m_vFrozenCols;//用来记录固定列宽的列 void FreezeColumn(int col);
.cpp中
void CMyListView::FreezeColumn(int col) { m_vFrozenCols.push_back(col); } BOOL CMyListView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { int len = m_vFrozenCols.size(); if(len > 0) { HD_NOTIFY* pHDN = (HD_NOTIFY*)lParam; switch(((NMHDR*)lParam)->code) { case HDN_BEGINTRACKW: case HDN_BEGINTRACKA: case HDN_DIVIDERDBLCLICKA: case HDN_DIVIDERDBLCLICKW: for(int i=0; i<len; i++) { if(pHDN->iItem == m_vFrozenCols[i]) //如果拖动的列是设定固定列宽的列之一 { *pResult = TRUE; return TRUE; } } } } return CListView::OnNotify(wParam, lParam, pResult); }
相关文章推荐
- Visual C++中MFC消息的分类
- IE8引发 VS2005/2008 MFC向导出错的解决方案
- VS2010/MFC编程入门之前言
- VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
- VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)
- VS2010/MFC编程入门之四(MFC应用程序框架分析)
- VS2010/MFC编程入门之五(MFC消息映射机制概述)
- VS2010/MFC编程入门之六(对话框:创建对话框模板和修改对话框属性)
- VS2010/MFC编程入门之七(对话框:为对话框添加控件)
- VS2010/MFC编程入门之八(对话框:创建对话框类和添加控件变量)
- VS2010/MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
- VS2010/MFC编程入门之十一(对话框:模态对话框及其弹出过程)
- VS2010/MFC编程入门之十二(对话框:非模态对话框的创建及显示)
- VS2010/MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)
- VS2010/MFC编程入门之十四(对话框:向导对话框的创建及显示)
- VS2010/MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)
- VS2010/MFC编程入门之十六(对话框:消息对话框)
- VS2010/MFC编程入门之十七(对话框:文件对话框)
- VS2010/MFC编程入门之十八(对话框:字体对话框)