Сколько строк должно быть в (основном) буфере виртуального элемента управления Listview?
Я представляю приложение на чистом «c» для Win32 API. Существует соединение ODBC с базой данных, которое извлекает элементы (фактически строки).
Пример кода MSDN подразумевает буфер фиксированного размера 30 для конечного кеша (что почти наверняка не будет оптимальным). Я думаю, что конечный кеш и основной кеш должны быть одинакового размера.
Я считаю, что буфер должен быть больше, чем максимальное количество элементов, которые могут отображаться в представлении списка за один раз. Я предполагаю, что это можно было пересчитывать каждый раз, когда размер Listivew изменялся?
Или лучше использовать большое фиксированное значение. Если да, то каково это значение?





Используйте ListView_ApproximateViewRect (или сообщение LVM_APPROXIMATEVIEWRECT), чтобы получить высоту прямоугольника просмотра.
Используйте ListView_GetItemRect (или сообщение LVM_GETITEMRECT), чтобы получить высоту элемента.
Разделите высоту прямоугольника вида на высоту элемента, чтобы получить количество элементов, которые могут поместиться в вашем представлении. Сделайте этот расчет для каждого события размера.
Затем создайте свой буфер соответствующим образом.
Уведомляющее сообщение LVN_ODCACHEHINT сообщит вам, сколько элементов будет запрашиваться. Это может помочь вам решить, насколько большим должен быть ваш кеш.
@Brian R. Bondy Спасибо за явную помощь в том, как получить количество элементов. Фактически, я был готов работать, чтобы понять, что это можно сделать (для просмотра списка или отчета) с помощью ListView_GetCountPerPage, и я бы использовал ваш способ получить его для других, хотя мне не нужен ListView_ApproximateViewRect, поскольку я все будут готовы узнать новый размер ListView.
@Lars Truijens Я уже использую LVN_ODCACHEHINT и думал об использовании его для установки размера буфера, однако мне нужно прочитать данные SQL до конца, чтобы найти последний элемент, чтобы получить количество строк, возвращаемых из ODBC. Поскольку это было бы лучшее время для заполнения «конечного кеша», я думаю, что мне нужно установить количество элементов (и, следовательно, заполнить буфер), прежде чем мы получим вызов LVN_ODCACHEHIN.
Думаю, мой настоящий вопрос - это оптимизация, на которую, как мне кажется, намекнул Брайан. Объем накладных расходов при очистке буфера и перераспределении памяти меньше, чем накладные расходы на выход в сеть и выполнение чтения ODBC, некоторые делают буфер довольно маленьким и часто меняют его.
Это правильно?
Я немного поигрался, и мне кажется, что LVN_ODCACHEHINT обычно правильно заполняет основной буфер и пропускает только в том случае, если строка (в режиме отчета) частично видна.
Итак, я думаю, что ответ на размер кеша: общее количество отображаемых элементов плюс одна строка отображаемых элементов (поскольку в представлениях значков у вас есть несколько элементов в строке).
Затем вы должны перечитать кеш с каждым WM_SIZE и LVN_ODCACHEHINT, если у них есть разные начальный и конечный номер элемента.
Казалось бы, ответ: (Или случайный набор заметок, пока я возился с идеями)
В качестве общего ответа для буферов: Начните с некоторого количества, в данном случае полного экрана (я добавляю дополнительную строку на случай, если следующая частично не закрыта), а затем каждый раз, когда экран прокручивается, удваивайте размер буфера (до момента, когда у вас закончится память ).
Что, казалось бы, неверно. Оказывается, большинство способов загрузки данных уже буферизированы. ODBC-вызовы файлового ввода-вывода. Практически все, что я не могу придумать, находится либо в памяти, либо пересчитывается на лету. Это означает, что ответ на самом деле таков: возьмите значения, указанные в LVN_ODCACHEHINT (и добавьте по 1 с каждой стороны - это просто работает быстрее, если у вас нет интегральной высоты).