首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

CListCtrl 欄位點擊排序完整實作指南

     編輯:VC++

核心機制

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)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved