Вход/Регистрация
Использование ListView в режиме виртуального списка
вернуться

Чадов Тимофей

Шрифт:

void CMyListView::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult) {

 LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;

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

 CMyDocument* pDoc = GetDocument;

 int nIndex= pItem->iItem;

 if (pItem->mask & LVIF_TEXT) //требуется текст?

 strcpy(pItem->pszText, pDoc->GetItemText(pItem->iSubItem, nIndex));

 if pItem->mask & LVIF_IMAGE) //требуется картинка

pItem->iImage= pDoc->GetItemImage(nIndex);

}

Здесь GetItemText и GetItemImage функции класса документа, возвращающие текст меток и номер изображения требуемого элемента соответственно.

По умолчанию виртуальный список не хранит информацию поля state, за исключением двух флагов LVIS_SELECTED и LVIS_FOCUSED. Это приводит к тому, что использование иконок состояния (state image) невозможно. Однако эту ситуацию легко исправить. Необходимо использовать сообщение LVM_SETCALLBACKMASK, позволяющее задать маску для хранимой списком информации об элементах.

// Разрешаем использовать иконки состояния

SendMessage(LVM_SETCALLBACKMASK, LVIS_STATEIMAGEMASK, 0);

Кажущиеся трудности

Итак, список создан и замечательно работает. Возможно, в некоторых случаях, Вам захочется реализовать и более сложные вещи.

Управление кешированием.

Если вы самостоятельно решили оперировать большими объемами информации – без кеширования не обойтись. Виртуальный список помогает оперировать процессом кеширования, посылая приложению уведомления 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, можно использовать возможности этой библиотеки. В большинстве практических случаев этого бывает достаточно.

Альтернатива в заключение

Виртуальный режим не единственный способ заставить список запрашивать информацию об элементах. Можно при добавлении элемента задать значение pszText структуры LVITEM равнымLPSTR_TEXTCALLBACK. В этом случае, также будут приходить уведомления LVN_GETDISPINFO. Однако при этом, придется самостоятельно заботиться о добавлении|удалении элементов, вместо одного вызова SetItemCount для виртуального режима. Кроме того, не будет заметного выигрыша в экономии памяти и скорости. Более подробно данный способ описан в статье Chris Maunder. Using text callbacks in ListView Controls.

  • Читать дальше
  • 1
  • 2
  • 3

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: