第一次用ListControl控件,不知道排序功能要怎么实现。虽然网上也找到了一些例子,但是都没有详细的说明文档。我摸索了很久还是没有理清楚其中的逻辑。一个字“菜”,两个字“很菜”。小弟特来求助,不知道哪里有详细的中文资料(e文太差),用于说明ListControl控件排序功能的实现,特别是那个回调函数的实现。请高手帮忙,谢谢!学习,关注……
解决方案 »
- 生产者与消费者//事件与wait函数一起使用为什么不行?
- 在对话框中编程中遇到的问题
- 找不到Dll入口点??
- windows template library 在哪下载?
- 求救!!我的msdn6.0现在出现如下情况,有的链接不能使用,如果一点的话就提示运行时间错误,重装了很多次,问题依旧!求各位大虾帮忙!
- 是否存在一个Windows的文件查找的Shell接口?或者其它类型的接口?
- ?????--??? To Visual C++
- 请问Microsoft Hierarchical FlexGrid Control控件在VC中如何与一个记录集邦定?
- 求助!请教高手:我的机子今天硬盘突然被人共享,关机重起后仍然被共享,并且老是出现错误提示,存在.dll文件错误连接!!
- 关于透明的Edit类
- 再问怎样在VC++的程序中运行一个java程序,3x
- 一个图形问题
http://www.pconline.com.cn/pcedu/empolder/gj/vc/0404/348784.html
http://www.vckbase.com/document/viewdoc/?id=243
Sorting the list based on text in any column - Zafir Anjum (1998/08/06)
http://www.codeguru.com/listview/sort_on_col_generic.shtml
Sort list based on text/numeric/date-time in any column - Tal J. Rosen (1998/08/06)
int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
//通过传递的参数来得到CSortList对象指针,从而得到排序方式
CSortList* pV=(CSortList*)lParamSort;
//通过ItemData来确定数据
DEMO_DATA* pInfo1=strAllData+lParam1;
DEMO_DATA* pInfo2=strAllData+lParam2;
CString szComp1,szComp2;
int iCompRes;
switch(pV->m_nSortedCol)
{
case(0):
//以第一列为根据排序
szComp1=pInfo1->szName;
szComp2=pInfo2->szName;
iCompRes=szComp1.Compare(szComp2);
break;
case(1):
//以第二列为根据排序
if(pInfo1->iAge == pInfo2->iAge)
iCompRes = 0;
else
iCompRes=(pInfo1->iAge < pInfo2->iAge)?-1:1;
break;
default:
ASSERT(0);
break;
}
//根据当前的排序方式进行调整
if(pV->m_fAsc)
return iCompRes;
else
return iCompRes*-1;
}
如果我要把排序的功能封装在一个CLstCtrl的派生类里面,您的方法好象不好用啊请指点,谢谢……学习……
this->SortItems(CompareFunction, (LPARAM)this);//CompareFunction函数
int CALLBACK CSortList::CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamData)
{
CSortList* pListCtrl = reinterpret_cast<CSortList*>( lParamData );
ASSERT( pListCtrl->IsKindOf( RUNTIME_CLASS( CListCtrl ) ) ); ItemData* pid1 = reinterpret_cast<ItemData*>( lParam1 );
ItemData* pid2 = reinterpret_cast<ItemData*>( lParam2 );
……
}我调试的时候发现:lParam1,lParam2 都为0
不知道是哪里出了问题?
是不是this->SortItems(CompareFunction, (LPARAM)this)里面的(LPARAM)this没有传给lParamData
还是另有原因?请高手指点,谢谢!学习,关注……
BOOL SortItems( PFNLVCOMPARE pfnCompare, DWORD dwData );
这就是系统提供给我们自定义排序的接口,第一个参数是我们排序的函数地址,第二个参数是在排序中我们传递给排序函数的相关需要的参数,例如:当前排序安装什么方式:升序,降序等等 有了上面的接口我们就需要定义自己的排序函数了,系统规定的格式是:
int CALLBACK Compare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
但是我们经常将其定义为改类的静态函数,这样列表控件的每个对象就可以共享了。现在我们了解一下参数的含义,参数1和参数2是系统传递给我们的,提供了需要比较的两个对象的信息(注意:这些信息都是需要我们提供的,下面说明),最后一个参数就是我们在调用SortItems是传递的参数。 有了比较的两个对象(参数1,参数2)已经比较的信息(参数3),我们就可以在Compare中写排序算法了,一般排序有数字排序,字符串排序,这里我就说明这两种,其他的就看自己的需要了CString str1 = ((ListData*)lParam1)->strText;
CString str2 = ((ListData*)lParam2)->strText;
int sOrder = (lParSortAsc & 0xFF) ? 1 : -1;
if (IsNumber(str1) && IsNumber(str2))
return (atol(str1) - atol(str2))*sOrder;
else
return (str1.Compare(str2))*sOrder; ListData是我们自己定义的数据结构用来存放比较的信息,代码非常简单我就不说明了,系统根据返回值的大小确定排序的结果,至于排序的次数我们就不需要考虑了,但我们调用SortItems函数后,系统自动调用回调函数,传递需要比较的对象,排序完成后SortItems函数也就返回了。 上面说明排序的方法,现在就说明排序的开始条件,在我们调用SortItems函数以前我们必须将排序的信息准备好,这样系统在回调的时候才能提供数据给我们的排序函数,代码如下for (int i = 0; i < NumItems; i++)
{
DWORD dwData = GetItemData(i);
CString strText = GetItemText(i, m_nSortedCol);
SetItemData(i, (DWORD)new ListData(dwData, strText));
} 我们将排序的信息以及原来的数据信息打包重新保存到列表控件每个对象的数据地址中,这个地址也就是回调函数传递参数1和2,这样我们比较的信息就能够正确传递到回调函数中了,当SortItems函数返回的时候,排序已经结束,列表控件中对象的顺序已经发生改变,现在我们只需要恢复原来的数据信息就可以了,如下for(i=0; i<NumItems; i++)
{
ListData* pData = (ListData*)GetItemData(i);
SetItemData(i, pData->dwOldData);
delete pData;
} 这样我们的排序功能就完成了,不过为了让排序结果让使用者一下就能看清楚,我们可以在列表控件的头部控件中根据当前列的排序状态显示相关的描述信息(比如:画个三角表示升序),这些方法我就不说明,大家看考代码就明白了,下面是演示程序图片开始状态
第二列升序排列(字符串)
第二列降序排列(字符串)
第四列升序排列(数字)
第四列降序排列(数字)
代码下载