您的位置:首页 > 其它

CListCtrl::SortItems的用法

2008-12-19 10:33 423 查看
CListCtrl::SortItems的用法:
(一)SortItems使用在哪?

CListCtrl::SortItems的原型是:
BOOL SortItems( PFNLVCOMPARE pfnCompare, DWORD dwData );
其中
1)第一个参数pfnCompare为回调函数,形式为:
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,
LPARAM lParamSort);

lParam1,lParam2是什么?这是SortItems难理解的原因。在(二)中介绍。
lParamSort实际上是列数,等于2)中的dwData。
2)第二个参数dwData为用户自定义值。
dwData实际传入的是列数,等于1)中的lParamSort。

下面是SortItems使用的地方:


//LVN_COLUMNCLICK消息响应函数


void CUpListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)




...{


NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;




//排序


//CompareFunc是回调函数


//pNMListView->iSubItem就是列数


SortItems( (PFNLVCOMPARE)CompareFunc, pNMListView->iSubItem );




*pResult = 0;


}



(二)SortItems的的回调函数的中的lParam1,lParam2是什么?

简单的说:是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 );


}

现在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://O列


//自己按0列规则排序代码


//想要pInfo1(所代表的item)排在pInfo2(所代表的item)之前,则nRet小于0;反之大于0;顺序不变等于0


break;


case 1://1列




//自己按1列规则排序代码


//...


break;


}




return nRet;


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: