MFC CListbox GetItemData失败

时间:2015-06-03 11:56:57

标签: c++ sorting mfc listbox

我使用DrawItem()重绘了CListbox。出于某些原因,我想使用自定义比较来使用我自己的规则对列表项进行排序,并使用LBS_SORTLBS_HASSTRING属性。在SetItemData()中使用OnInitDialog()后,我在DrawItem()中获取了这些数据,但它无效。代码如下:

初始化代码

void OnInitDialog(...) 
{
    .........
    m_List.SetListHeight (40);

    for (int i = 0 ; i < 20 ; i ++) {
        m_List.AddString ((const char *) i);
        m_List.SetItemData (i,(100 + i));
    }
    ....
}

比较代码

int CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct) 
{       
    ASSERT(lpCompareItemStruct->CtlType == ODT_LISTBOX);

    int     a = lpCompareItemStruct->itemData1;
    int     b = lpCompareItemStruct->itemData2;

    return (a - b);
}

重绘代码:

DrawItem (lpDIS) 
{
        ..................
        CString     str;

        int         i = (int) GetItemData (lpDIS->itemID); // the i is not what I expect. 

        str.Format ("%d", (int) i);

        dc.DrawText (str,CRect (&lpDIS->rcItem), DT_CENTER | DT_VCENTER | DT_SINGLELINE); 
        ...................
}

当我使用

        ***index = m_List.addstring ((const char *) i) ;
        m_List.setitemdata (index,(100 + i));***

它可以工作,但如果我使用struct添加string,则索引不对,代码如下所示:

struct      test {
    int     a,b,c,d;
};

init_code :

            test        *ptest = new test[20];      /* just a test ,we don't delete memory till application ends */

    for (int i = 0 ; i < 20 ; i ++) {
        ptest [i].a = i;
        int index = m_List.AddString ((const char *) (ptest + i));
        m_List.SetItemDataPtr (index,(void *) (100 + i));
    }

compare code :

int ListEx::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct) 
{
    // TODO: Add your code to determine the sorting order of the specified items
    // return -1 = item 1 sorts before item 2
    // return 0 = item 1 and item 2 sort the same
    // return 1 = item 1 sorts after item 2

//  ASSERT(lpCompareItemStruct->CtlType == ODT_LISTBOX);

    test *pa,*pb;

    pa = (test *) lpCompareItemStruct->itemData1;  // crashed here 
    pb = (test *) lpCompareItemStruct->itemData2;

//  ASSERT (pa);
//  ASSERT (pb);

    return (pa->a - pb->a);
}

draw_item code :

        CString     str;

        test  *ptest = (test *) (lpDIS->itemData);

        str.Format ("%d", (int) ptest->a);

        dc.DrawText (str,CRect (&lpDIS->rcItem), DT_CENTER | DT_VCENTER | DT_SINGLELINE); 

addstring只能使用字符串??? 如果该项是结构数据,我如何将这些结构数据设置为列表框项

2 个答案:

答案 0 :(得分:0)

在OnInitDialog中你应该这样做:

for (int i = 0 ; i < 20 ; i ++) {
   int index = m_List.AddString ((const char *) i);
   m_List.SetItemData (index, 100 + i);
}

AddString返回插入项目的索引(如果列表已排序,则可以是任何位置)。 m_List.SetItemData (index ,(100 + i))设置您刚刚插入的项目的数据。

答案 1 :(得分:0)

我们可以将结构数据设置为列表框。

struct _empInfo {
    CString strName;
    ..............
} empInfo = {L"XYZ",...};

m_list.AddString(empinfo.strName);

我在我的应用程序中尝试了上面的代码..