2015-06-03 95 views
0

我用DrawItem()來重畫我的CListbox。由於某些原因,我想使用自定義比較來按我自己的規則對我的列表項進行排序,並且我使用LBS_SORT並且沒有LBS_HASSTRING屬性。在OnInitDialog()中使用SetItemData()之後,我在DrawItem()中獲得了這些數據,但它不起作用。代碼如下圖所示:MFC CListbox GetItemData失敗

初始化代碼

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));*** 

它的工作原理,但如果我用一個結構來addstring,該指數是不正確的,代碼如下所示:

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能只使用字符串? 如果項目是一個結構數據,我怎麼能設置這些結構數據到列表框項???

+0

這意味着我我們getitemdata()是不是我想要的。 –

回答

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))設置您剛剛插入的項目的數據。

+0

非常感謝,另一個問題,當我使用addstring((const char *)i)時,它可以工作,但是如果我使用結構來增加字符串,它將不起作用... –

+0

@true_casey:很難說,沒有看到你的代碼。 –

+0

該列表可能會丟失數據,因爲如果存在基礎重定位,則不會複製項目數據。我見過這種行爲在Windows 8.1平臺上,並解決它,我只是連續兩個循環... –

0

我們可以將結構數據設置爲列表框。

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

m_list.AddString(empinfo.strName); 

我上面我的應用程序代碼試圖..

+0

我想我已經解決了它... LBS_SORT和沒有LBS_HASSTRING意味着SetItemData,SetItemDataPtr AddString是相同的東西,所以你可以只使用只用其中的一個.... LBS_SORT和LBS_HASSTRING意味着內CListBox的將ALLOC的extral內存來存儲字符串.. 這是它們之間的區別我想 –

+0

檢查此鏈接HTTPS:/ /msdn.microsoft.com/en-us/library/windows/desktop/bb775149%28v=vs.85%29.aspx – abhi312

+0

我做了一個測試,代碼是這樣的 \t'for(int i = 0; i < 20; i ++){' \t \t'int index = m_List。AddString((常量字符*)(ⅰ));' \t \t'm_List.SetItemDataPtr(指數,(無效*)(10000 + I));' \t'}' INT draw_item(),: \t \t'CString的\t \t STR;' \t \t'INT A =(int)的GetItemDataPtr(索引);' \t \t'INT b =(int)的lpDIS->的ItemData;' \t \t'str.Format(」 a =%d,b =%d「,(int)a,(int)b);' lpDIS-> itemData和getitemdata是相同的價值... **事實證明,我是對的.... ** –