我是用vs2008sp1写的程序
代码如下,出现的问题是SortItems传递给SortFunc的lparam1 和lparam2所指向的地址的内容不是我SetItemData的内容是一些很随机的数字
        //listShow 是CListCtrl, ITEMDATA是一个结构体
         //为了不遗漏一些可能的细节我还是把这些密切相关的代码写出来,麻烦大家了
/////////////////////////////////////////初始化的代码位于对话框窗口的初始化那个地方////////////////////////////////////////
listShow.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
listShow.SetBkColor(RGB(247,247,255));
listShow.SetTextColor(RGB(0,0,255));
listShow.SetTextBkColor(RGB(247,247,255)); listShow.InsertColumn(0,LPCTSTR(TEXT("学号")),LVCFMT_LEFT,50);
listShow.InsertColumn(1,LPCTSTR(TEXT("名字")),LVCFMT_LEFT,70);
listShow.InsertColumn(2,LPCTSTR(TEXT("数学")),LVCFMT_LEFT,50);
listShow.InsertColumn(3,LPCTSTR(TEXT("英语")),LVCFMT_LEFT,50);
listShow.InsertColumn(4,LPCTSTR(TEXT("计算机")),LVCFMT_LEFT,50);
listShow.InsertColumn(5,LPCTSTR(TEXT("平均分")),LVCFMT_LEFT,50);
listShow.InsertColumn(6,LPCTSTR(TEXT("数学名次")),LVCFMT_LEFT,60);
listShow.InsertColumn(7,LPCTSTR(TEXT("英语名次")),LVCFMT_LEFT,60);
listShow.InsertColumn(8,LPCTSTR(TEXT("计算机名次")),LVCFMT_LEFT,80);
listShow.InsertColumn(9,LPCTSTR(TEXT("总名次")),LVCFMT_LEFT,50);
listShow.InsertItem(0,LPCTSTR(TEXT("8")));
listShow.SetItemText(0,1,LPCTSTR(TEXT("Enzo")));
CString a = TEXT("a1");
CString b = TEXT("a2");
CString c = TEXT("a3");
ITEMDATA pd ;
pd.id = 7; // 这个是为了保险才一个成员一个成员地赋值的
pd.name = c;
pd.math = 45;
pd.english = 37;
pd.computer = 79;
pd.average = 53;
pd.englishposition = 1;
pd.mathposition = 45;
pd.computerposition = 7;
pd.wholeposition = 8; listShow.SetItemData(0,(DWORD_PTR)&pd); ITEMDATA pd1;
pd1.id = 6;
pd1.name = c;
pd1.math = 14;
pd1.english = 54;
pd1.computer = 7;
pd1.average = 45;
pd1.englishposition = 45;
pd1.mathposition = 78;
pd1.computerposition = 78;
pd1.wholeposition = 78; listShow.InsertItem(1,LPCTSTR(TEXT("3")));
listShow.SetItemData(1,(DWORD_PTR)&pd1);
ITEMDATA pd2;
pd2.id = 1;
pd2.name = c;
pd2.math = 65;
pd2.english = 34;
pd2.computer = 89;
pd2.average = 23;
pd2.englishposition = 2;
pd2.mathposition = 32;
pd2.computerposition = 2;
pd2.wholeposition = 4;
listShow.InsertItem(2,LPCTSTR(TEXT("2")));
listShow.SetItemData(2,(DWORD_PTR)&pd2);
///////////////////////////////////////////////////////////////////////////////
/////////////////////////这是我的回调函数////////////////////////////////////////
///////////////////////我在下面的某个位置(看注释)设置了断点/////////////////////////
int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
int nRetVal = 0; PITEMDATA pData1 = (PITEMDATA)lParam1;
PITEMDATA pData2 = (PITEMDATA)lParam2;
switch(lParamSort)
{
case 0: // id
nRetVal =pData1->id - pData2->id;
break; case 1: // name
nRetVal = pData1->name.Compare(pData2->name);
break; case 2: // math
nRetVal = pData1->math - pData2->math;
break; case 3: // english
nRetVal = pData1->english - pData2->english;
break; case 4: // computer
nRetVal = pData1->computer - pData2->computer;
break; case 5: // average
nRetVal = pData1->average - pData2->average;
break; case 6: // math position
nRetVal = pData1->mathposition - pData2->mathposition;
break;

case 7: // english position
nRetVal = pData1->englishposition - pData2->englishposition;
break; case 8: // computer position
nRetVal = pData1->computerposition - pData2->computerposition;
break; case 9: // whole position
nRetVal = pData1->wholeposition - pData2->wholeposition;
break; default:
break;
}
if (nRetVal == 0)
nRetVal = pData1->id - pData2->id;
////////////////我在这里设置了断点,发现pData1 和 pData2的值与我setitemdata的完全不同///////
///////////////////////程序能够很正常地运行,但是如果那两个数据不准确的话,那么整个ClistCtrl的排序就没有意义了////
return nRetVal;
}
//////////////////这是按CListCtrl的某一列后的反应函数///////////////////////////////////
void CStudentInfoDlg::OnLvnColumnclickShow(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
listShow.SortItems(SortFunc,pNMLV->iSubItem);
*pResult = 0;
}感谢大家花那么多时间看完

解决方案 »

  1.   

    ITEMDATA应该用指针或者全局变量,这样的话出了初始化的函数它作用域就结束了,数据也被删除了。亲身体验啊。。
      

  2.   

    注意sortitem时回调函数得到的是:lParam所以插入是一定要赋值.与SetItemData无关的
    LVITEM lvi;
    lvi.mask=LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE;
    // fill list
    lvi.iSubItem=0;// name
    lvi.iItem=current;
    //lparam will be used when sortitems !
    lvi.lParam=current;