list控件排序的时候常见的方法是:使用List控件的SortItems函数和回调函数
int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)。
参见下面的代码:
// 在OnColumnclickList中调用函数SortItems
m_listTest.SortItems( ListCompare, (DWORD)&m_listTest );  
......
int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
    ……
}这个回调函数的lParam1和lParam1接收ItemData,而lParamSort接收list控件指针。
我的问题是:
在m_listTest.SortItems调用ListCompare时并没有指定吧ItemData传递给lParam1和lParam1呀!也没有显式的传递控件的指针给lParamSort呀!这是怎么回事呢?难道调用回调函数并不需要显式指定传进区的参数??

解决方案 »

  1.   

    你怎么知道呢,SortItems有显式调用ListCompare吗?
      

  2.   

    你要先给每行数据设置上itemdata,setdata好象就可以吧,最近刚研究出来,大致就是这样/。
      

  3.   

    如果要用SortItems排序,在构建item的时候要指定它的lparam参数值(还要记得置Mask的相应位),此值就是回调函数中的值,回调函数每次传入两个Item的lparam值,然后进行运算.
      

  4.   

    我是提问者:
    呵呵,我想这个问题的关键是调用回调函数的时候并没有显式的传递参数给回调函数,那参数是怎么传进去的呢?
    baojian88888(机器人)问我怎么知道的,其实偶也不知道,只是看了VCHelp上闻怡洋的那篇文章。他排序的思路如下:
    首先初始化列表;再写响应函数OnColumnclickList,在这个函数里调用回调函数ListCompare;然后定义回调函数。
    下面是他的部分关键代码:
    // 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);
    }
    ///////////////////////////////////////////////////////
    // OnColumnclickList
    m_listTest.SortItems( ListCompare, (DWORD)&m_listTest ); 
    ///////////////////////////////////////////////////////
    // ListCompare
    int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
    CSortList* pV=(CSortList*)lParamSort;
    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;
    }我看了半天也没有看明白回调函数的参数是怎么传进去的!pianoman(神父) 说“在构建item的时候要指定它的lparam参数值(还要记得置Mask的相应位)”,闻怡洋的代码里也没有看见他是怎么设置的呀!还请高手拨开层层迷雾呀!!!
      

  5.   

    MFC的CListCtrl.SortItems函数内部通过发送LVM_SORTITEMS消息(也可以使用ListView_SortItems宏),而处理LVM_SORTITEMS消息是在ListView控件内部完成的,你可以认为这是一个API函数,所以你看不到显式调用回调函数的。因为这个排序的过程有点复杂,所以微软把它封装了。类似的比如C运行库的快速排序qsort函数,你也看不到那个Compare函数的显式调用的。至于传入参数到底是什么,看微软的MSDN解释。
      

  6.   

    我是提问者:
    这所以这么关心怎样传递参数给回调函数,我是想能否修改回调函数,比如传递四个参数进去。我修改了一下回调函数ListCompare的名字发现,名字是可以改变的!我想能不能改变参数的个数呢?但是我不知道怎么传递参数进去呀!
    能不能?:)
      

  7.   

    回调函数的参数个数和类型都是不能改变的
    一般参数的类型是LPARAM或DWORD,如果你想传入更多的数据,要采用传指针的方法,强制类型转换