VC之列表控件排序

本文简单介绍下VC列表控件排序功能实现。

1.新建对话框应用程序

新建对话框应用程序,并且添加List列表控件。

VC之列表控件排序_第1张图片


2.添加相关变量和函数

class CListSortDlg : public CDialog
{
// Construction
public:
	int m_nSortSign2;
	int m_nSortSign1;
	CListSortDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	//{{AFX_DATA(CListSortDlg)
	enum { IDD = IDD_LISTSORT_DIALOG };
	CListCtrl	m_list2;
	CListCtrl	m_list1;
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CListSortDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	//{{AFX_MSG(CListSortDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg void OnColumnclickList1(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnColumnclickList2(NMHDR* pNMHDR, LRESULT* pResult);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
private:
	void SetListInit2();
	void SetListInit();
};

3.初始化

初始化变量

	SetListInit();
	SetListInit2();

	m_nSortSign1 = 1;
	m_nSortSign2 = 1;

初始化列表

void CListSortDlg::SetListInit()
{
	//属性设置
	m_list1.ModifyStyle(LVS_TYPEMASK,LVS_REPORT&LVS_TYPEMASK|LVS_SINGLESEL);
	DWORD dwStyle = m_list1.GetExtendedStyle();
	m_list1.SetExtendedStyle(dwStyle|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
	
	//设置行宽
	CImageList image;
	image.Create(1,30,ILC_COLOR24|ILC_MASK,4,0);
	m_list1.SetImageList(&image,LVSIL_SMALL);
	
	//设置字体和大小
	CFont font;
	font.CreateFont(16,0,0,0,FW_NORMAL,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"宋体");
	m_list1.SetFont(&font);
	m_list1.GetHeaderCtrl()->SetFont(&font);
	
	//设置标题头
	m_list1.InsertColumn(0,"序号",LVCFMT_LEFT,80,0);
	m_list1.InsertColumn(1,"姓名",LVCFMT_LEFT,120,0);
	m_list1.InsertColumn(2,"年龄",LVCFMT_LEFT,80,0);
	
	//设置内容
	m_list1.InsertItem(0,"001");
	m_list1.SetItemText(0,1,"小明");
	m_list1.SetItemText(0,2,"18");
	
	m_list1.InsertItem(1,"002");
	m_list1.SetItemText(1,1,"小红");
	m_list1.SetItemText(1,2,"17");
	
	m_list1.InsertItem(2,"003");
	m_list1.SetItemText(2,1,"小华");
	m_list1.SetItemText(2,2,"19");
}

void CListSortDlg::SetListInit2()
{
	//属性设置
	m_list2.ModifyStyle(LVS_TYPEMASK,LVS_REPORT&LVS_TYPEMASK|LVS_SINGLESEL);
	DWORD dwStyle = m_list2.GetExtendedStyle();
	m_list2.SetExtendedStyle(dwStyle|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
	
	//设置行宽
	CImageList image;
	image.Create(1,30,ILC_COLOR24|ILC_MASK,4,0);
	m_list2.SetImageList(&image,LVSIL_SMALL);
	
	//设置字体和大小
	CFont font;
	font.CreateFont(16,0,0,0,FW_NORMAL,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"宋体");
	m_list2.SetFont(&font);
	m_list2.GetHeaderCtrl()->SetFont(&font);
	
	//设置标题头
	m_list2.InsertColumn(0,"序号",LVCFMT_LEFT,80,0);
	m_list2.InsertColumn(1,"姓名",LVCFMT_LEFT,120,0);
	m_list2.InsertColumn(2,"年龄",LVCFMT_LEFT,80,0);
	
	//设置内容
	m_list2.InsertItem(0,"001");
	m_list2.SetItemText(0,1,"小明");
	m_list2.SetItemText(0,2,"18");
	
	m_list2.InsertItem(1,"002");
	m_list2.SetItemText(1,1,"小红");
	m_list2.SetItemText(1,2,"17");
	
	m_list2.InsertItem(2,"003");
	m_list2.SetItemText(2,1,"小华");
	m_list2.SetItemText(2,2,"19");
}


4.排序

方案一:只对指定栏排序

系统函数
int CALLBACK SortData1(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
	CListSortDlg* pDlg = (CListSortDlg*)lParamSort;
	if (!pDlg)
	{
		return 0;
	}
	
	CListCtrl &list = (CListCtrl&)(pDlg->m_list1);
	
	WORD wSubItem = 0;
	WORD nItem1 = lParam1;
	WORD nItem2 = lParam2;
	
	CString sItem1 = list.GetItemText(nItem1,wSubItem);
	CString sItem2 = list.GetItemText(nItem2,wSubItem);
	
	if (sItem1 < sItem2)
	{
		return pDlg->m_nSortSign1;
	}
	else
	{
		return -1*pDlg->m_nSortSign1;
	}
	
	return 0;
}

排序事件
void CListSortDlg::OnColumnclickList1(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	if (0 == pNMLV->iSubItem)
	{
		int cnt = m_list1.GetItemCount();
		for (int i=0; i<cnt; i++)
		{
			m_list1.SetItemData(i,i);
		}
		m_list1.SortItems(SortData1,DWORD(this));
		
		if (m_nSortSign1 >=0)
		{
			m_nSortSign1 = -1;
		}
		else
		{
			m_nSortSign1 = 1;
		}
	}
	
	*pResult = 0;
}

方案二:对所有栏排序

系统函数
int CALLBACK SortData2(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
	CListSortDlg* pDlg = (CListSortDlg*)lParamSort;
	if (!pDlg)
	{
		return 0;
	}
	
	CListCtrl &list = (CListCtrl&)(pDlg->m_list2);
	
	WORD wSubItem = (lParam1&0xFFFF0000)>>16;
	WORD nItem1 = lParam1&0x0000FFFF;
	WORD nItem2 = lParam2&0x0000FFFF;
	
	CString sItem1 = list.GetItemText(nItem1,wSubItem);
	CString sItem2 = list.GetItemText(nItem2,wSubItem);
	
	if (sItem1 < sItem2)
	{
		return pDlg->m_nSortSign2;
	}
	else
	{
		return -1*pDlg->m_nSortSign2;
	}
	
	return 0;
}

排序事件
void CListSortDlg::OnColumnclickList2(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here

	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	if (-1 < pNMLV->iSubItem)
	{
		DWORD dwItemData = 0;
		int cnt = m_list2.GetItemCount();
		for (int i=0; i<cnt; i++)
		{
			dwItemData = pNMLV->iSubItem;
			dwItemData = dwItemData<<16;
			dwItemData = dwItemData+i;
			m_list2.SetItemData(i,dwItemData);
		}
		m_list2.SortItems(SortData2,DWORD(this));

		if (m_nSortSign2 >=0)
		{
			m_nSortSign2 = -1;
		}
		else
		{
			m_nSortSign2 = 1;
		}
	}
	
	*pResult = 0;
}

5.效果

运行程序
VC之列表控件排序_第2张图片

点击列表1标题栏,试试点击不同的栏的效果
VC之列表控件排序_第3张图片

点击列表2标题栏,试试点击不同的栏的效果




VC之列表控件排序_第4张图片


源码下载


你可能感兴趣的:(排序,VC,列表控件)