关于CListCtrl排序问题

由于项目需要,在做到一个功能时,需要一个对话框上面的CListCtrl根据用户点击的列表不同,而实现排序功能。查阅了很多资料,总结如下:

1、使用VC++编程,微软在内部对CListCtrl已经有一部分的辅助排序实现代码,自己需要添加简单的函数即可实现。

2、自己需要添加的部分:

      (1)响应点集标题栏事件函数,并在这个函数里面添加一些简单的实现代码       

void CBudPointMoreDlg::OnLvnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码

	ItemData* myData = new ItemData;
	myData->listctrl = &m_pointsumlist;
	myData->isub = pNMLV->iSubItem;

	//为了对不同列的点击在0,1之间,即正序和反序之间进行选择
	int sortnum=(int)GetProp(m_pointsumlist.GetSafeHwnd(),"SORT_COLUMN");
	int sortasc=(int)GetProp(m_pointsumlist.GetSafeHwnd(),"SORT_DIRECTION");

	if(sortnum==pNMLV->iSubItem)
	{
		sortasc=(sortasc+1)%2;
		SetProp(m_pointsumlist.GetSafeHwnd(),"SORT_DIRECTION",(HANDLE)sortasc);
	}

	SetProp(m_pointsumlist.GetSafeHwnd(),"SORT_COLUMN",(HANDLE)pNMLV->iSubItem);
	myData->seq=sortasc;

	m_pointsumlist.SortItems(CompareFunc,(LPARAM)myData);

	DeletePointer(myData);

	*pResult = 0;
}
      

      (2)需要添加自己的回调函数,实现对字符串和数字的排序

//排序函数实现
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
	//通过传递的参数来得到CSortList对象指针,从而得到排序方式
	ItemData* pItemMyData=(ItemData*)lParamSort;

	//通过ItemData来确定数据
	CListCtrl* list =pItemMyData->listctrl;
	int isub=pItemMyData->isub;

	LVFINDINFO findInfo; 
	findInfo.flags = LVFI_PARAM; 
	findInfo.lParam = lParam1; 
	int iItem1 = list->FindItem(&findInfo, -1); 
	findInfo.lParam = lParam2; 
	int iItem2 = list->FindItem(&findInfo, -1); 

	CString strItem1 =list->GetItemText(iItem1,isub); 
	CString strItem2 =list->GetItemText(iItem2,isub);

	int iCompRes;
	switch(pItemMyData->isub)
	{
	case(0):
		//以第一列为根据排序
		iCompRes=strcmp(strItem1,strItem2);
		break;
	case(1):
		//以第二列为根据排序
		if(1/*pInfo1->iAge == pInfo2->iAge*/)
		{
			iCompRes = 0;
		}
		else
		{
			/*iCompRes=(pInfo1->iAge < pInfo2->iAge)?-1:1;*/
		}
		break;
	default:
		ASSERT(0);
		break;
	}

	//根据当前的排序方式进行调整
	if(pItemMyData->seq)
	{
		return iCompRes;
	}
	else
	{
		return iCompRes*(-1);
	}
}

      (3)最关键的,也是大多数网上文章没有详细提到,或者提到没有详细说明的。就是在列表中添加数据后,一定要调用以下函数。这个函数里面的i是添加数据的行序号,有多少行,就调用多少次。一般在循环里面调用。

m_pointsumlist.SetItemData(i,(DWORD)i);

写的比较糙,适合有一定编程基础,又看过网上相关资料的,自己又动手写了代码,但是总是实现不对的人来看。后续会放一个代码示例。在我的资源中可以下载到。


你可能感兴趣的:(关于CListCtrl排序问题)