虚拟列表用来解决大量数据的实时显示问题,据说可以解决列表框闪烁问题(实验时还是有一点闪)。但据说用了虚拟列表后,不能自由进行排序。关于这点,参考这篇网文。想出来一个折衷的办法:即使用全局变量+qsort+自定义比较函数的做法来进行排序。
解决方法是:先设置两个全局变量(在某个CPP文件中):
int column_sort; BOOL bSortAscending; 在派生的CListCtrl类实现文件中进行声明:
extern int column_sort; extern BOOL bSortAscending; 为每个ListCtrl设置一个比较函数(用来传给qsort函数)。在CListCtrl的派生类(这里是CMyVirtualList)中添加反射通知消息
BEGIN_MESSAGE_MAP(CMyVirtualList, CListCtrl) //... ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
//... END_MESSAGE_MAP() 然后在类的定义中添加OnColumnClick的声明:
void CMyVirtualList::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult) ; 类的实现文件中添加此函数的实现代码: void CMyVirtualList::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{ NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if(m_funcSort == NULL) return; // TODO: Add your control notification handler code here int clickedCol = pNMListView->iSubItem; if(column_sort == clickedCol) bSortAscending = !bSortAscending; else { column_sort = clickedCol; bSortAscending = TRUE; } qsort(m_ppData, count, sizeof(DATA*), m_funcSort);//只要对数据排好序就可以了 SetItemCount(count); //force redraw *pResult = 0;
} m_funcSort是CListCtrl派生类.h文件中添加的成员变量:SORTFUNC m_funcSort;
同样在:typedef int (* SORTFUNC )(const void *, const void *); 定义了函数指针类型。 并定义成员函数:void SetCmpFunction(SORTFUNC p); 其实现如下: //设置排序时的比较函数 void CMyVirtualList::SetCmpFunction(SORTFUNC p) { m_funcSort = (SORTFUNC)p; } 因为每个List的数据都不同,所以如果需要使用虚拟列表技术,则需要为每个列表定一个CListCtrl派生类。否则实现起来比较麻烦,需要知道每列数据的类型以便进行比较。排序用的比较函数也需要根据不同虚拟列表中列数和每列数据的类型来编写。 |
|