日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CListCTrl控件排序(一)

發布時間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CListCTrl控件排序(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來源網站:http://blog.csdn.net/hgy413/article/details/6719908


列表控件(CListCtrl)的排序功能不像其它直接調用API就可以完成的功能一樣.它比較復雜.今天將我的一點體會簡單地談一下. 列表控件的頂部有一排按鈕,用戶可以通過選擇不同的列來對記錄進行排序。但是 CListCtrl并沒有自動排序的功能,我們需要自己添加一個用于排序的回調函數來比較兩個數據的大小,此外還需要響應排序按鈕被點擊的消息。回調函數就好像是一個中斷處理函數,操作系統在符合你設定的條件時自動調用。?
·CListCtrl提供了用于排序的函數?
函數原型為:?
BOOL CListCtrl::SortItems( PFNLVCOMPARE pfnCompare, DWORD dwData);?
其中第一個參數為全局排序函數(它就是回調函數)的地址,?
第二個參數為用戶數據,你可以根據你的需要傳遞一個數據或是指針。?
該函數返回-1,代表第一項排應在第二項前面;?
返回1代表第一項排應在第二項后面;?
返回0代表兩項相等。·排序函數原形為:?
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進行存取。在添加項時選用特定的CListCtrl::InsertItem也可以設置該值。由于你在排序時只能通過該值來確定項的位置所以你應該比較明確的確定該值的含義。?
·我們什么時候需要排序(消息映射)呢??
實現這點可以在父窗口中對LVN_COLUMNCLICK消息進行處理來實現。

例子:?

//排序回調函數實現 static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { <span style="white-space:pre"> </span>// lParamSort contains a pointer to the list view control. <span style="white-space:pre"> </span>// The lParam of an item is just its index. <span style="white-space:pre"> </span>//以第一列為根據排序 <span style="white-space:pre"> </span>CListCtrl* pListCtrl = (CListCtrl*) lParamSort; <span style="white-space:pre"> </span>CString strItem1 = pListCtrl->GetItemText(lParam1, 0); <span style="white-space:pre"> </span>CString strItem2 = pListCtrl->GetItemText(lParam2, 0); //比較兩個數 <span style="white-space:pre"> </span>LPCTSTR s1=(LPCTSTR)strItem1; <span style="white-space:pre"> </span>LPCTSTR s2=(LPCTSTR)strItem2; <span style="white-space:pre"> </span>int n1=atoi(s1); <span style="white-space:pre"> </span>int n2=atoi(s2);if (n1>n2) <span style="white-space:pre"> </span>return -1; <span style="white-space:pre"> </span>else <span style="white-space:pre"> </span>return 1; } <span style="white-space:pre"> </span>void C***::OnColumnclickList(NMHDR* pNMHDR, LRESULT* pResult) { <span style="white-space:pre"> </span>NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; <span style="white-space:pre"> </span>// TODO: Add your control notification handler code here //調用排序函數 <span style="white-space:pre"> </span>m_ShowData.SortItems( MyCompareProc, (DWORD)&m_ShowData ); <span style="white-space:pre"> </span>*pResult = 0;}
整個過程是這樣的: 當你點擊列表控件的表頭時,此時它會向父窗口發送LVN_COLUMNCLICK消息,此時響應函數OnColumnclickList(),在該函數里面再調用列表控件的SortItems()成員函數,它會自動調用排序函數,完成排序功能.?


首先,要讓CListCtrl能響應點擊Column header的操作,方法是響應對應的LVN_COLUMNCLICK消息,然后在對應的消息處理函數中執行自己的排序。其方法是調用CListCtrl 類中的成員函數SortItems()函數,不過在調用之前,依據msdn的指示,一定要對所有需要排序的行調用CListCtrl的 SetItemData(?int?nItem,?DWORD?dwData?)函數,一般的設置方法為:
for(int i = 0; i < listCtrl.GetItemCount(); ++i)
{
SetItemData(i,i);
}
這樣寫的原因下面馬上就會指出。
接下來就是調用CListCtrl的排序函數SortItems(?PFNLVCOMPARE?pfnCompare,?DWORD?dwData?),其中第一個參數為比較函數(回調函數),其函數格式按照msdn上的說法應該為:
int CALLBACK listCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);?
這里的lParam1和lParam2都是系統傳給這個回調函數的,具體數值就是上面SetItemData函數中的dwData,
第二個參數是輸入給這個回調函數的一個參數,一般都是對應CListCtrl對象的指針
最后就是實現那個回調函數了,msdn上說這個函數必須為獨立的函數,或者是某個類中的靜態函數,這點注意一下即可,以下為一個具體的回調函數的例子:

/// //按第六列排序 int CALLBACK listCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { CListCtrl* pListCtrl = (CListCtrl*)lParamSort; CString strItem1 = pListCtrl->GetItemText(lParam1,5); CString strItem2 = pListCtrl->GetItemText(lParam2,5); LVCOLUMN Vol; CString csStr(""); TCHAR szCol[MAX_PATH]; Vol.pszText = szCol; Vol.mask=LVCF_TEXT; Vol.cchTextMax=sizeof(szCol); pListCtrl->GetColumn(0,&Vol); csStr = CString(Vol.pszText); if (csStr.Right(1) == CString("▼")) { return _tcscmp(strItem2.GetBuffer(MAX_PATH),strItem1.GetBuffer(MAX_PATH)); } else if (csStr.Right(1) == CString("▲")) { return _tcscmp(strItem1.GetBuffer(MAX_PATH),strItem2.GetBuffer(MAX_PATH)); } else { return _tcscmp(strItem1.GetBuffer(MAX_PATH),strItem2.GetBuffer(MAX_PATH)); } } /// void CManageView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; // TODO: Add your control notification handler code here CListCtrl &m_ListCtrl = GetListCtrl();for(int i = 0; i < m_ListCtrl.GetItemCount(); ++i) m_ListCtrl.SetItemData(i,i); m_ListCtrl.SortItems(listCompare,(LPARAM)&m_ListCtrl);*pResult = 0; }

轉載于:https://www.cnblogs.com/lovelyx/p/4867143.html

總結

以上是生活随笔為你收集整理的CListCTrl控件排序(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。