您的位置:首页 > 其它

MFC_ListView

2014-03-15 16:46 549 查看
1. 获取当前选择行

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mfc CListView