Здравствуйте товарищи.
Сделал давеча Virtual ListView и столкнулся со следующей неприятностью: при прокрутке списка с большим количеством элементов он моргает зело отменно. Explorer же так непристойно себя не ведет. Понятно, конечно, что господа из M$ делали все через OwnerDraw, но почему нельзя было сразу сделать все по человечески!? (Это вопрос естественно риторический.) Другой вопрос в том, можно ли это вылечить, так сказать, малой кровью, без использования OwnerDraw?
Носок исчез в гильбертовом пространстве. Туда ему и дорога.
Здравствуйте, last shindji, Вы писали:
LS>Здравствуйте товарищи. LS>Сделал давеча Virtual ListView и столкнулся со следующей неприятностью: при прокрутке списка с большим количеством элементов он моргает зело отменно. Explorer же так непристойно себя не ведет. Понятно, конечно, что господа из M$ делали все через OwnerDraw, но почему нельзя было сразу сделать все по человечески!? (Это вопрос естественно риторический.) Другой вопрос в том, можно ли это вылечить, так сказать, малой кровью, без использования OwnerDraw?
Можно обрабатывать LVN_ODCACHEHIT и кэшировать необходимыые строки. Однако ж:
Note that this message is not always an exact representation of the items that will be requested by LVN_GETDISPINFO. Therefore, if the requested item is not cached while handling LVN_GETDISPINFO, the application must be prepared to supply the requested information from a source outside the cache.
HgLab: Mercurial Server and Repository Management for Windows
Здравствуйте, last shindji, Вы писали:
LS>Сделал давеча Virtual ListView и столкнулся со следующей неприятностью: при прокрутке списка с большим количеством элементов он моргает зело отменно.
Не замечал. Скомпилируй пример из студии — ничего не моргает.
LS>Explorer же так непристойно себя не ведет.
Не замечал. При первой прокрутке моргает — видно как сначала заполняется список файлов без иконок (в Report view), а потом по очереди появляются иконки файлов.
LS>Понятно, конечно, что господа из M$ делали все через OwnerDraw, но почему нельзя было сразу сделать все по человечески!? (Это вопрос естественно риторический.)
А ты думаешь, что господа из M$ делали Common Controls для удобства программистов? (вопрос естественно риторический.) Наивный, они их делали под себя, в т.ч. под Explorer. И никакого OwnerDraw они не используют (не царское это дело), все нужные им функции там и так уже заложены. Если сомневаешься — проверь Spy++.
Re: Virtual LIstView: продолжение эпопеи.
От:
Аноним
Дата:
29.06.04 09:17
Оценка:
1. Просветите пожалуйста, как это можно проверять функции с помощью Spy++, очень интересно.
2. Действительно, Explorer использует для просмотра папок окно с именем класса "SysListView32" (очевидно, без IShellView не обошлось).
3. При относительно большом количестве элементов (ок. 16 тыс.) моргание наблюдается даже при элементарном копировании константной стоки в соответствующий буфер (в реальном приложении все данные кэшируются).
4. Экспериментировал с CImagelist`ом. При указании рисовать иконки с глубиной цвета >= 24 bpp выделенные элементы закрашиваются полупрозрачным-синим в шахматном порядке (один пиксел остается как есть, другой закрашивается), нехорошо. При этом, еще и не учитывается градиент теней новых иконок XP, которые с градиентной маской тени. Видел я, однако, приложения, в которых все иконы отображаются также как в Explorer (иконостас используется совсем не для просмотра файловой системы) — например VirtualCD. Неужели эти товарищи расширяют Shell namespace и используют Shell View? Чудеса.
Здравствуйте, Аноним, Вы писали:
А>1. Просветите пожалуйста, как это можно проверять функции с помощью Spy++, очень интересно.
С помощью Spy++ видно что стиль LVS_OWNERDRAWFIXED не стоит. Кстати, он работает только в Report view, а в других view Owner Draw не поддерживается. Есть только Custom Draw.
А>3. При относительно большом количестве элементов (ок. 16 тыс.) моргание наблюдается даже при элементарном копировании константной стоки в соответствующий буфер (в реальном приложении все данные кэшируются).
Какой буфер, кто моргает и отчего? Как обновляется ListView после копирования?
А>4. Экспериментировал с CImagelist`ом. При указании рисовать иконки с глубиной цвета >= 24 bpp выделенные элементы закрашиваются полупрозрачным-синим в шахматном порядке (один пиксел остается как есть, другой закрашивается), нехорошо. При этом, еще и не учитывается градиент теней новых иконок XP, которые с градиентной маской тени. Видел я, однако, приложения, в которых все иконы отображаются также как в Explorer (иконостас используется совсем не для просмотра файловой системы) — например VirtualCD. Неужели эти товарищи расширяют Shell namespace и используют Shell View? Чудеса.
Это глюки CImageList. Нужно грузить иконки через WinAPI. Поиск должен помочь.
Здравствуйте, last shindji, Вы писали:
LS>Понятно, конечно, что господа из M$ делали все через OwnerDraw, но почему нельзя было сразу сделать все по человечески!? (Это вопрос естественно риторический.)
Понятно только то, что легче бросить камень в MS, чем искать проблемы у себя...
Как Вам уже показали, Explorer не использует OWNERDRAW. Более того, это тривиальный SysListView32, даже не subclass'ed.
Есть множество способов оптимизировать код — проверьте как быстро Вы отвечаете на GETDISPINFO? Вызываете ли SetRedraw(FALSE) / SetRedraw(TRUE)? Установили ли WS_CLIPCHILDREN у родительского окна?
Здравствуйте, VladFein, Вы писали:
LS>>Понятно, конечно, что господа из M$ делали все через OwnerDraw, но почему нельзя было сразу сделать все по человечески!? (Это вопрос естественно риторический.)
VF>Понятно только то, что легче бросить камень в MS, чем искать проблемы у себя...
Конечно, жизнь без проблем была бы скучна и неинтересна, однако, отсутствие четких ориентиров относительно их преодоления, при достижении определенного предела, может заставить человека переквалифицироваться в священники (†Аллилуя MS†).
VF>Как Вам уже показали, Explorer не использует OWNERDRAW. Более того, это тривиальный SysListView32, даже не subclass'ed.
Посыпаю голову пеплом.
VF>Есть множество способов оптимизировать код — проверьте как быстро Вы отвечаете на GETDISPINFO? Вызываете ли SetRedraw(FALSE) / SetRedraw(TRUE)? Установили ли WS_CLIPCHILDREN у родительского окна?
Длео в том, что SetRedraw(FALSE) / SetRedraw(TRUE) я вызывал, в обработчике LVN_GETDISPINFO оставлял только копирование константной строки в буфер pszText структуры LVITEM, являющейся параметром сообщения, даже пытался извращаться с CUSTOMDRAW, однако это ни к чему не привело (родительское окно у меня CMainFrame). Более того, нашел на сайте статью
про Virtual ListView, в демонстрационном примере к которой наблюдается такое же моргание при прокрутке (поиск про загрузку иконок через WinAPI ничего на дал). Неужели вы сами с таким не сталкивались? Не глумитесь, пожалуйста, над бедным зулусским программистом и помогите добрым словом.
Носок исчез в гильбертовом пространстве. Туда ему и дорога.
Здравствуйте, last shindji, Вы писали:
LS>Длео в том, что SetRedraw(FALSE) / SetRedraw(TRUE) я вызывал,
А вот это зря. Может из-за этого и моргает.
LS> в обработчике LVN_GETDISPINFO оставлял только копирование константной строки в буфер pszText структуры LVITEM, являющейся параметром сообщения,
Константную строку можно не копировать, а передать адрес.
LS> даже пытался извращаться с CUSTOMDRAW, однако это ни к чему не привело (родительское окно у меня CMainFrame).
А CUSTOMDRAW чем может помочь?
LS> Более того, нашел на сайте статью
про Virtual ListView, в демонстрационном примере к которой наблюдается такое же моргание при прокрутке (поиск про загрузку иконок через WinAPI ничего на дал).
Да вроде нормально моргает, как же как Эксплорер. Можешь еще посмотреть пример в MSDN VListVw или DirLV в Q234310