Populating a List Control with the sorted contents of an `std::multimap`?

469 views Asked by At

As a follow-up to this question, I need a way to access my data by index. But the data needs to be sorted by timestamp, contain a filepath as a value, and be displayed in real-time as new elements are discovered.

Considering that multiple files/folders could potentially contain an identical timestamp, I've decided to go with std::multimap as the container of choice to store my data. However, this complicates the process of populating my List Control, since LVITEM::iItem is an index value used to determine which element of data is to be displayed in a control with the LVS_OWNERDATA flag set (i.e., virtual lists).

I can't seem to find a way to access my data by index in order to get the timestamp keys & filepath values, so what could I do to correct this issue?

1

There are 1 answers

1
Remy Lebeau On BEST ANSWER

You cannot access the content of a std::multimap by index directly. But what you can do is store your sorted data in a std::multimap and then store iterator values in a separate std::vector and use that as the data source for your ListView. When the ListView asks for data by index, go to your std::vector and use the iterator at the specified index to access your data in the std::multimap. When you insert() a new item in a std::multimap(), it returns an iterator for that item, and existing iterators are not invalidated by inserts.

std::multimap<MyItemData> mydata;
std::vector<std::multimap<MyItemData>::iterator> lvdata;

...

std::multimap<MyItemData>::iterator iter = mydata.insert(...);
lvdata.push_back(iter);
SendMessage(hwndLV, LVM_SETITEMCOUNT, lvdata.size(), LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);

...

case LVN_GETDISPINFO:
{
    NMLVDISPINFO *pdi = reinterpret_cast<NMLVDISPINFO*>(lParam);
    std::multimap<MyItemData>::iterator iter = lvdata[pdi->item.iItem];
    // use *iter as needed...
    break;
}