Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Реализация прокрутки (Scroll)


Автор: Emura 27.7.2009, 16:16
уважаемые, подскажите пожалуйста советом.
реализую прокрутку, с чистого листа. выбираю путь реализации.

логика:
1. получаем Top, Left на основе действий скроллбаров.
2. рисуем на канвасе (из точки 0,0).
3. по возможности рисуем только то что будет видимо в итоге (не рисуем лишнего)
4. смещаем канвас в нужные координаты

для смещения(шаг 4) нашел два способа:

1) ScrollWindow
2) SetViewportOrgEx/SetWindowOrgEx

ScrollWindow -показался медленным.. 
SetViewportOrgEx/SetWindowOrgEx - не понял еще)

может еще что упустил? Кто занимался подобным поделитесь опытом, советом)






Автор: ИванМ 29.7.2009, 20:41
Я просто вручную перерисовываю. Если рисовать только то, что должно быть видно на экране, скорость получалась нормальная.

Автор: GremlinProg 29.7.2009, 22:24
Цитата(Emura @  27.7.2009,  18:16 Найти цитируемый пост)
ScrollWindow -показался медленным.. 

не понял, а чем он медленный, с чем сравнивал?
Цитата(ИванМ @  29.7.2009,  22:41 Найти цитируемый пост)
Я просто вручную перерисовываю. Если рисовать только то, что должно быть видно на экране, скорость получалась нормальная.

на это и ориентирован ScrollWindow, он дает тебе рисовать только то, что изменилось,
без дополнительных расчетов, конечно, если им правильно пользоваться

SetViewportOrgEx/SetWindowOrgEx - это функции, которые адресуют битмап на холсте,
удобны как раз когда ты точно знаешь, какой "квадрат" на холсте нужно закрасить,
а координаты самого холста при этом менять не хочешь

холст - HDC
битмап - HBITMAP

где-то у меня был пример двойного буфера с SetWindowOrgEx, посмотри, как эта функция там себя ведет, очень удобно,
но если ей слишком злоупотреблять, например, как по твоей задумке (мои экстрасенсорные предположения) - двигать координаты холста в след за скроллбарами, то основная работа WM_PAINT'а будет - отсечение, а не рисование

Автор: Emura 30.7.2009, 14:16
ИванМ
Цитата

Я просто вручную перерисовываю. Если рисовать только то, что должно быть видно на экране, скорость получалась нормальная. 

согласен, но это реально когда рисуемое однотипно и его не много, с прочими вариантами это уже лишнее колдовство с кодом, когда везде и всюду надо учитывать смещение.. слишком трудоемко.

GremlinProg 
Цитата

не понял, а чем он медленный, с чем сравнивал?


да особо не с чем, время позамерял, скорей всего не правильно использую.

как себе представляю это:

В качестве примера, есть 3 строки. в видимости может находится только одна строка. 
например видима вторая строка.
1.рисуем строки
а) смотрим что первая не видна -пропускаем
б) вторая видна рисуем
в) третья не видна break;
2. сдвигаем холст  на вторую строку с помощью ScrollWindow


GremlinProg, поправь если наврал. может попроще можно\нужно?


Автор: GremlinProg 30.7.2009, 15:52
со строками можно проще,
если у строк фиксированая высота, то можно сразу расчитать номер первой видимой строки и число видимых строк,
а затем, в одном цикле вывести все видимые строки

причем, если использовать встроенный скроллбар, то расчет первой видимой строки можно передать ему
нужно настроить его так, чтобы GetScrollPos всегда давал номер строки, а не смещение в пикселах,
это реализуется стандартными средствами, через SetScrollInfo

Автор: Emura 30.7.2009, 20:54
GremlinProg
строки как пример, такую идею и применил. а с нестроками такой подход верный? 

Автор: GremlinProg 30.7.2009, 22:12
конечно, 
строки, списки, таблицы, сетки - все, что имеет фиксированный размер

зачем расчитывать видимость каждого элемента, если на расчет смещения и числа сразу всех видимых элементов достаточно потратить всего пару операций

Автор: Emura 30.7.2009, 22:33
GremlinProg, спасибо за инфу!
а вот как быть с картинками которые "не влезают", и требуют прокрутку smile 

Автор: victor79 7.8.2009, 19:46
StretchBlt - нарисовать указанный кусок из картинки

Автор: GremlinProg 7.8.2009, 20:21
с картинками-то все как раз проще:
настраиваешь попиксельную прокрутку на габариты картинки,
а саму картинку рисуешь, уже опираясь на GetScrollPos и размеры клиентской области,
тут подойдет и BitBlt, если масштабирование не требуется

можно, конечно спозиционировать битмап в hdc на {-x,-y}
и рисовать картинку полностью, с нулевой позиции,

но попробуй рисовать так большие кодированные или сжатые картинки, типа jpeg,
сразу увидишь изрядное притормаживание,

потому что жипег, в таком случае, будет подготавливаться для вывода на весь свой размер,
и распаковыватся полностью, а при выводе, большая его часть будет просто отсекаться,
вот и выйдет, что непосредственно на рисование его будет уходить только малая доля от всего того времени,
которое будет реально потрачено

с позиционированием лучше так не делать,
либо делать, но при рисовании, опираться непосредственно на координаты битмапа в пределах холста: GetClipBox
так потерь будет намного меньше

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)