Home > Blockchain >  How to virtual List control using a map data structure'?
How to virtual List control using a map data structure'?

Time:11-02

I have a question while studying C MFC.

void AnchorDlg::OnGetdispinfoListctrl(NMHDR *pNMHDR, LRESULT *pResult)
{

    NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);

    LV_ITEM* pItem = &(pDispInfo)->item;
    CString str;
    if(pItem == NULL) return;

    int nRow = pItem->iItem;
    int nCol = pItem->iSubItem;

    if(nRow<0 || nRow >= mapShip->size()) return;

    auto iter = mapShip->begin();

    if(pItem->pszText)
    {
        switch(nCol)
        {
        case 1:
            str.Format(_T("%.0f"), iter->second->mmsi);
            //str.Format(_T("%.0f"), iter->second->mmsi);
            lstrcpy(pItem->pszText, str);
            break;
        case 2:
            str.Format(_T("%.7f"), iter->second->lat);
            lstrcpy(pItem->pszText, str);
            break;
        case 3:
            str.Format(_T("%.7f"), iter->second->lng);
            lstrcpy(pItem->pszText, str);
            break;
        case 4:
            str.Format(_T("%.1f"), iter->second->sog);
            lstrcpy(pItem->pszText, str);
        case 5:
            str.Format(_T("%.1f"), iter->second->cog);
            lstrcpy(pItem->pszText, str);
        }
    }
    *pResult = 0;
}

mapShip consists of double and data objects.

I want to print out 1000 data, but only one data is printed.

I've used iter but only one data is output. Same data print repeat.

I must used map data structure.

I don't know how to use the map.

CodePudding user response:

You don't seem to do anything with pItem->iItem (nRow), you just set it to the beginning of the list. You should instead search your data with this - requests may arrive in any random order. You don't have to iterate the list in OnGetdispinfoListctrl(), instead you should return the data to be displayed, given the iItem and iSubItem members. So consider using a more efficient structure to hold your data, if they are really too many (lists are not, because they are serial access structures, not random access ones). Also, don't copy the text into Item.pszText, instead set Item.pszText to point to your data. The if(pItem->pszText) check is not needed, neither is correct:

void AnchorDlg::OnGetdispinfoListctrl(NMHDR *pNMHDR, LRESULT *pResult)
{
    NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);

    LV_ITEM* pItem = &(pDispInfo)->item;

    // Persistent Buffer
    static CString str;

    if (pItem == NULL) return;

    int nRow = pItem->iItem;
    int nCol = pItem->iSubItem;

    if (nRow < 0 || nRow >= mapShip->size()) return;

    //auto iter = mapShip->begin();
    auto iter = SearchMyData(nRow);

    switch (nCol)
    {
        case 1:
            str.Format(_T("%.0f"), iter->second->mmsi);
            pItem->pszText = str;
            break;
        case 2:
            str.Format(_T("%.7f"), iter->second->lat);
            pItem->pszText = str;
            break;
        case 3:
            str.Format(_T("%.7f"), iter->second->lng);
            pItem->pszText = str;
            break;
        case 4:
            str.Format(_T("%.1f"), iter->second->sog);
            pItem->pszText = str;
            break;
        case 5:
            str.Format(_T("%.1f"), iter->second->cog);
            lstrcpy(pItem->pszText, str);
    }
    *pResult = 0;
}

CodePudding user response:

A virtual list-view control is a list-view control that doesn't store any data. Instead, users just tell the control how many items there are (by sending a LVM_SETITEMCOUNT message), and the control implementation will subsequently call back to the user to provide the data for the individual cells (by way of the LVN_GETDISPINFO message).

While the code in question is responding to the LVN_GETDISPINFO message, evaluating the nRow (and nCol) identifying the cell to be displayed, it doesn't use that data for information lookup. The code perpetually accesses the first item (mapShip->begin()) for display. However, it should be using nRow to index into the data represented by mapShip (see How to Use Virtual List-View Controls for an example).

Assuming that mapShip is an instantiation of the std::map class template, you'll want to index into that map using nRow as the index, e.g.:

auto const& value = mapShip[nRow];

and use value in place of iter. This will display items in the order they are stored in the associative container (sorted by key). If you need a different ordering, you'll have to map nRow onto the respective index in the map.

  • Related