CListCtrl 实现排序功能(数字和字母)

通过CListCtrl显示全部的进程信息,并且点击CListCtrl控件的头按钮 会进行升序或是降序进程排序。


一、其中 CListCtrl控件的排序有几个要点这里列出来:

1.

BOOL CListCtrl::SortItems( PFNLVCOMPARE pfnCompare, DWORD dwData); 
其中第一个参数为全局排序函数(它就是回调函数)的地址, 
第二个参数为用户数据,你可以根据你的需要传递一个数据或是指针。 
该函数返回-1,代表第一项排应在第二项前面; 
返回1代表第一项排应在第二项后面; 
返回0代表两项相等

2.回调函数

int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); 
其中第三个参数为调用者传递的数据(即调用SortItems时的第二个参数dwData)。 
第一和第二个参数为用于比较的两项的ItemData,你可以通过DWORD CListCtrl::GetItemData( int nItem )/ 
BOOL CListCtrl::SetItemData( int nItem, DWORD dwData )来对每一项的ItemData进行存取。

注意:回调函数只能为全局函数或是静态类成员函数

3.响应LVN_COLUMNCLICK事件,当单击控件头按钮时触发


二、正确代码:

以下代码可以实现CListCtrl控件的升序/降序并且分字符串和数字进行排序。

1.结构体和回调函数

struct SortData
{
     CListCtrl *listctrl;                 //CListCtrl控件指针
     int isub;        //列号
     int isAsc;        //1为升序,0为降序
};

//回调函数
int static CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
{
     SortData *paramSort=(SortData *)lParamSort;
     CListCtrl* list =paramSort->listctrl;
     int isub=paramSort->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);

	 //将CString转换成char*
	wchar_t *chItem1,*chItem2;
	chItem1=(LPWSTR)strItem1.GetBuffer(strItem1.GetLength());
	chItem2=(LPWSTR)strItem2.GetBuffer(strItem2.GetLength());

	 //判断字符串是否都是数字
	 int count=0;
	 for(int i=0;i<strItem1.GetLength();i++)
	 {
		 if(!isdigit(chItem1[i]))
		 {
			 count++;
		 }
	 }
	  //分情况进行比较
	 if(count<=1)
	 {
		 int intItem1 =_ttol(chItem1);
		 int intItem2 = _ttol(chItem2);
			int sum =(intItem1>=intItem2 ? -1:1);
			if(paramSort->isAsc)
				return sum;
			else
				return -sum;
	 }else
	 {
		 if(paramSort->isAsc)                                     
			 return strItem1.CompareNoCase(strItem2);
		 else
			 return strItem2.CompareNoCase(strItem1);
	 }
}


2//响应LVN_COLUMNCLICK事件

void CProp_Process::OnColumnclickListProcess(NMHDR* pNMHDR, LRESULT* pResult) 
{
     NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
     // TODO: Add your control notification handler code here
      SortData *paramSort=new SortData;
     paramSort->listctrl=&m_ListCtrl; //m_ListCtrl 为CListCtrl控件的关联变量
     paramSort->isub=pNMListView->iSubItem;
     int sortNum=(int)GetProp(m_ListCtrl.GetSafeHwnd(),_T("SORT_COLUMN"));
     int sortAsc=(int)GetProp(m_ListCtrl.GetSafeHwnd(),_T("SORT_DIRECTION"));
     if(sortNum==pNMListView->iSubItem){
        sortAsc=(sortAsc+1)%2;
        SetProp(m_ListCtrl.GetSafeHwnd(),_T("SORT_DIRECTION"),(HANDLE)sortAsc);
     }
     SetProp(m_ListCtrl.GetSafeHwnd(),_T("SORT_COLUMN"),(HANDLE)pNMListView->iSubItem);
     paramSort->isAsc=sortAsc;
     m_ListCtrl.SortItems(CompareFunc,(LPARAM)paramSort);

     *pResult = 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/lovelyx/p/4867140.html