52480.fb2
Итак, список создан и замечательно работает. Возможно, в некоторых случаях, Вам захочется реализовать и более сложные вещи.
Если вы самостоятельно решили оперировать большими объемами информации – без кеширования не обойтись. Виртуальный список помогает оперировать процессом кеширования, посылая приложению уведомления LVN_ODCACHEHINT, в которых передает информацию о диапазоне элементов, которые необходимо отобразить на экране. Эту информацию можно использовать для динамического выделения памяти под требуемое число элементов и заполнения их корректными значениями.
void CMyListView::OnOdcachehint(NMHDR* pNMHDR, LRESULT* pResult) {
NMLVCACHEHINT* pCacheHint = (NMLVCACHEHINT*)pNMHDR;
// Подготовить кеш
PrepareCach(pCacheHint->iFrom, pCacheHint->iTo);
*pResult = 0;
}
Реализация функции, подобной PrepareCach, зависит от того, каким способом вы храните и обрабатываете данные, и может быть различной в зависимости от решаемой задачи. Данное уведомление всего лишь своевременная подсказка.
Когда списку необходимо найти специфический элемент, он посылает уведомление LVN_ODFINDITEM. Это может случиться, если требуется реализовать нажатие быстрой клавиши (поиск по имени), или элемент получил сообщение LVM_FINDITEM. Информация для поиска передается в двух структурах NMLVFINDITEM и LVFINDINFO. В них содержится: номер элемента, с которого следует начать поиск; элемент искомой строки; направление поиска и т.п.
void CMyListView::OnOdfinditem(NMHDR* pNMHDR, LRESULT* pResult) {
NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)pNMHDR;
LVFINDINFO FindItem = pFindInfo->lvfi;
if (FindItem.flags & LVFI_STRING) {
//ишем FindItem.psz начиная pFindInfo->iStart
*pResult = GetDocument()->FindItem(FindItem.psz, pFindInfo->iStart);
return;
}
*pResult = –1;
}
Обработчик уведомления должен вернуть номер искомого элемента или –1 в случае неудачи.
Трудности? Это еще что такое? Однако бесплатный сыр сами знаете где. Дело в том, что, так как сами элементы в списке не хранятся, придется самим заботится о сортировке. Не удастся воспользоваться функцией CListCtrl::SortItems, бесполезно писать CompareItems и т.п. Все, что у вас есть – это порядковый номер элемента.
Но, нет худа без добра. Действительно, обладая дополнительной информацией об используемых данных, можно выбрать более подходящую функцию сортировки, а значит – повысить производительность. Кроме того, в ряде случаев, даже такая проблема не стоит. Если информация берется из базы данных, нет необходимости самостоятельно сортировать элементы, достаточно учесть это при составлении запроса. При использовании в качестве хранилища элементов контейнеров из STL, можно использовать возможности этой библиотеки. В большинстве практических случаев этого бывает достаточно.