CList 点击表头排序 (1)SortItems函数
點擊表頭排序整體的思路都是去?CListCtrl類中的方法SortItems去實現
CListCtrl::SortItems的原型是:
BOOL SortItems( PFNLVCOMPARE pfnCompare, DWORD dwData );
第一個參數pfnCompare為回調函數,形式為:
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,?LPARAM lParamSort);
lParam1,lParam2是什么?這是SortItems難理解的原因。
?
簡單的說:是LV_ITEM::lParam。
LV_ITEM是個結構,見msdn。
?
可見,我們在向CListCtrl插入item時,必須使用
int InsertItem( const LVITEM* pItem );
InsertItem有好幾種形式,只有這種形式才能夠使用LV_ITEM::lParam。
下面是插入item的代碼的一個示例:
???tagInfo?*pFileInfo?=?new?tagInfo;//tagInfo是個結構,存儲了你排序的所需要的信息。
????pFileInfo->strFileName?=?strFileName;
????pFileInfo->strFileSize?=?FormatFileSize(filefind.GetLength());
????pFileInfo->strFileType?=?GetTypeName(lpszFileName);
????//pFileInfo->strFilePath?=?strPath;
????int?nItem?=?GetItemCount();
????int?nIcon?=?GetIconIndex(lpszFileName,?filefind.IsDirectory(),?FALSE);???
????
?????LV_ITEM?lvi;
????lvi.mask?=?LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE;
????lvi.iItem?=?nItem;
????lvi.iSubItem?=?0;
????lvi.pszText?=?(LPTSTR)(LPCTSTR)pFileInfo->strFileName;
????lvi.lParam?=?(LPARAM)pFileInfo;
????lvi.iImage?=?nIcon;
????
????????if(?(nItem?=?InsertItem(&lvi))?!=?-1?)//插入文件名(即第0列),并顯示相應圖標
????{????
????????//MessageInt(nItem);
????????lvi.mask?=?LVIF_TEXT;????????
????????lvi.iItem?=?nItem;
????????//設置第1列(即設置文件大小)????????
????????lvi.iSubItem?=?1;????????????
????????if(!filefind.IsDirectory())//如果不是目錄
????????{????
????????????lvi.pszText?=?(LPTSTR)(LPCTSTR)pFileInfo->strFileSize;
????????????SetItem(?&lvi?);
????????}
????????else//如果是目錄
????????{????????
????????????lvi.pszText?=?(LPTSTR)YCT_UNKNOW_SIZE;
????????????SetItem(?&lvi?);
????????}????????????????????
????????????????
????????//設置第2列(即設置文件類型)
????????lvi.iSubItem?=?2;
????????lvi.pszText?=?(LPTSTR)(LPCTSTR)pFileInfo->strFileType;
????????SetItem(?&lvi?);
????????//設置第3列(即設置文件所在目錄)
????????lvi.iSubItem?=?3;
????????lvi.pszText?=?(LPTSTR)(LPCTSTR)strPath;
????????SetItem(?&lvi?);
????????//更新界面
????????//Update(?lvi.iItem?);
????}
?
第二個參數dwData為用戶自定義值。
dwData實際傳入的是列數,等于1)中的lParamSort。
?
void?CUpListCtrl::OnColumnclick(NMHDR*?pNMHDR,?LRESULT*?pResult)?
{
????????NM_LISTVIEW*?pNMListView?=?(NM_LISTVIEW*)pNMHDR;
????????//排序
????????//CompareFunc是回調函數
????????//pNMListView->iSubItem就是列數
SortItems(?(PFNLVCOMPARE)CompareFunc,?pNMListView->iSubItem?);
????????*pResult?=?0;
}
?
現在lParam指向的是new出來的空間,當然要用delete刪除。以下是刪除代碼:
//LVN_DELETEITEM消息響應函數
//每刪除一個item,系統都要自動調用這個函數的
void?CUpListCtrl::OnDeleteitem(NMHDR*?pNMHDR,?LRESULT*?pResult)?
{
????NM_LISTVIEW*?pNMListView?=?(NM_LISTVIEW*)pNMHDR;
????//刪除LV_ITEM::lParam所指向的空間
????LV_ITEM?lvi;
????lvi.mask?=?LVIF_PARAM;
????lvi.iItem?=?pNMListView->iItem;
????lvi.iSubItem?=?0;
????if?(?GetItem(?&lvi?)?)
????{
????????CUpListCtrl::tagInfo*?pInfo?=?(CUpListCtrl::tagInfo*)(lvi.lParam);
????????delete?pInfo;
????}
????
????*pResult?=?0;
}
?
?
(三)編寫回調函數
?
這個就比較簡單了,按你的規則排序就可以了。
這里回調函數是個靜態成員函數。
int?CALLBACK?CUpListCtrl::CompareFunc(CUpListCtrl::tagInfo*?pInfo1,?CUpListCtrl::tagInfo*?pInfo2,?LPARAM?lCol)
{
//CListCtrl::SortItems使用的回調函數
//[IN]pInfo1,pInfo2:傳入的是LV_ITEM::lParam,在調用InsertItem(const?LVITEM*?pItem)時指定
//[IN]lCol:指定列數(從零開始),即按哪一列排序
????int?nRet?=?0;
????ASSERT(lCol>=0?&&?lCol<NumCol-1);
????ASSERT(pInfo1?!=?NULL);
????ASSERT(pInfo2?!=?NULL);
????switch(lCol)
????{
????case?0://0列
????????????//自己按0列規則排序代碼
????????????????//想要pInfo1(所代表的item)排在pInfo2(所代表的item)之前,則nRet小于0;反之大于0;順序不變等于0
????????break;
????case?1://1列
????????//自己按1列規則排序代碼
????????????????//...
????????break;
????}
????return?nRet;
}
我會在下兩篇講解如何去實現排序
CList 點擊表頭排序 (2)兩種排序方法中其中一種
CList 點擊表頭排序 (3)兩種排序的第二種
?
轉載于:https://www.cnblogs.com/ye-ming/p/9262819.html
總結
以上是生活随笔為你收集整理的CList 点击表头排序 (1)SortItems函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序左到右联动
- 下一篇: Occlusion(遮挡剔除)