CListCtrl 提供 SortItems(PFNLVCOMPARE pfnCompare, DWORD dwData),需自行實作回呼比較函數:
-1:項目 1 排項目 2 前1:項目 1 排項目 2 後0:相等比較函數原型:int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)。lParam1/2 為項目的 ItemData(由 SetItemData 設定),lParamSort 為呼叫 SortItems 時傳入的 dwData。
LVN_COLUMNCLICK父視窗處理表頭點擊通知,切換排序欄位與升/降序,呼叫 SortItems。
struct DEMO_DATA {
char szName[20];
int iAge;
} strAllData[5] = {{"王某",30},{"張某",40},{"武某",32},{"陳某",20},{"李某",36}};
class CSortList : public CListCtrl {
public:
CSortList();
BOOL m_fAsc; // TRUE=升序, FALSE=降序
int m_nSortedCol; // 目前排序欄位
};
BOOL CSort_in_list_ctrlDlg::OnInitDialog() {
CDialog::OnInitDialog();
m_listTest.InsertColumn(0, "姓名");
m_listTest.InsertColumn(1, "年齡");
m_listTest.SetColumnWidth(0, 80);
m_listTest.SetColumnWidth(1, 80);
for (int i=0; i<5; i++) {
m_listTest.InsertItem(i, strAllData[i].szName);
char szAge[10];
sprintf(szAge, "%d", strAllData[i].iAge);
m_listTest.SetItemText(i, 1, szAge);
m_listTest.SetItemData(i, i); // ItemData = 陣列索引
}
return TRUE;
}
void CSort_in_list_ctrlDlg::OnColumnclickList1(NMHDR* pNMHDR, LRESULT* pResult) {
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if (pNMListView->iSubItem == m_listTest.m_nSortedCol)
m_listTest.m_fAsc = !m_listTest.m_fAsc; // 同欄位切換升降序
else {
m_listTest.m_fAsc = TRUE;
m_listTest.m_nSortedCol = pNMListView->iSubItem;
}
m_listTest.SortItems(ListCompare, (DWORD)&m_listTest);
*pResult = 0;
}
int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) {
CSortList* pList = (CSortList*)lParamSort;
DEMO_DATA* pInfo1 = strAllData + lParam1;
DEMO_DATA* pInfo2 = strAllData + lParam2;
int iCompRes = 0;
switch (pList->m_nSortedCol) {
case 0: // 姓名欄
iCompRes = strcmp(pInfo1->szName, pInfo2->szName);
break;
case 1: // 年齡欄
if (pInfo1->iAge == pInfo2->iAge) iCompRes = 0;
else iCompRes = (pInfo1->iAge < pInfo2->iAge) ? -1 : 1;
break;
default: ASSERT(0);
}
return pList->m_fAsc ? iCompRes : -iCompRes;
}
lParamSort 傳遞資料集指標或結構體,比較函數內動態取得正確資料來源。ItemData 可存指標指向完整物件,比較函數轉型後存取任意成員。HDF_SORTUP/DOWN 風格與 HDM_SETITEM)。