Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.189.177] |
|
Сообщ.
#1
,
|
|
|
Добрый день!
Подскажите пожалуйста, как можно рисовать на скроллбаре, например в TMemo? Добавлено Про WM_NCPAINT я в курсе, но рисовать поверх скроллбара не получается, все рисуется под ним. |
Сообщ.
#2
,
|
|
|
Рисутся не под ним, просто перезатирается самим скролом. Проще рисовать скрол полностью самому, отключив штатный и выделив под него место через WM_NCCALCSIZE
|
Сообщ.
#3
,
|
|
|
Rouse_, не могли бы вы привести небольшой пример? Полностью делать, разумеется, не надо, а просто базовый шаблон, который можно взять за основу?
|
Сообщ.
#4
,
|
|
|
Цитата estra @ Про WM_NCPAINT я в курсе, но рисовать поверх скроллбара не получается, все рисуется под ним. Теоретически можно, но можно ли это в компоненте Delphi возможностями Delphi - не известно. --- Технология такая - делаем саб-классинг контрола (перехватываем его оконную процедуру). Разрешаем при этом работать оригинальной оконной процедуре контрола. После того, как отработает WM_PAINT оригинальной оконной процедуры, дорисуем на поверхности контрола что-нибудь ещё. Такое я делал, работало устойчиво, но на WINAPI (c++). |
Сообщ.
#5
,
|
|
|
ЫукпШ увы с VCL такое не проходит.
|
Сообщ.
#6
,
|
|
|
Цитата estra @ увы с VCL такое не проходит. почему ?? В обработчике WM_PAINT сначала вызываешь inherited, потом делаешь, что хочешь. Должно работать |
Сообщ.
#7
,
|
|
|
Цитата jack128 @ почему ?? Потому что скролл перезатирает все, рисуясь поверх всего нарисованного. Думаю подход предложенный _Rouse в данном случае будет самым правильным решением. |
Сообщ.
#8
,
|
|
|
Цитата estra @ не могли бы вы привести небольшой пример? Ну вот основу вот тут можешь подсмотреть. По такому принципу разные скины пишутся. https://stackoverflow.com/questions/3753190...bar-delphi?rq=1 |
Сообщ.
#9
,
|
|
|
Rouse_, спасибо, самое то! Уже начал экспериментировать, посмотрим что получится...
|
Сообщ.
#10
,
|
|
|
Цитата estra @ Потому что скролл перезатирает все, рисуясь поверх всего нарисованного. Эм, ты сказал, что именно в VCL такое не прокатывает. Типа в WinApi - оно будет работать. Вот мне и интересно где тут ограничение именно VCL? Перехват WM_PAINT - это полный аналог, того что предлагал ЫукпШ (насколько я знаю) |
Сообщ.
#11
,
|
|
|
А какое отношение WM_PAINT имеет к NC области, к которой собственно и относится скроллбар? ))
|
Сообщ.
#12
,
|
|
|
Цитата Rouse_ @ А какое отношение WM_PAINT имеет к NC области, к которой собственно и относится скроллбар? )) Скролл-бар - это такой же контрол, как и все остальные. У него есть хэндл и его оконная процедура обрабатывает WM_PAINT. А кто ещё, интересно, обновляет изображение контрола ? Просто бывают составные контролы, включающие в себя несколько стандартных - комбо-бокс, например. --- Если мы хотим дорисовывать на поверхности контрола, значит мы должны перехватить его оконную процедуру. И обработать это сообщение после действий его оригинальной процедуры. --- Возможно, это уже сделано средствами используемой библиотеки. И тогда надо просто знать, как этим пользоваться. Возможно, сама библиотека так написана, чтобы препятствовать этим меропрятиям. Это тоже надо знать. Если возникли какие-то трудно преодолимые трудности с библиотекой, можно создать скролл-бар самостоятельно, как отдельный контрол: hwndWin = CreateWindowEx ( styleEx, _T("SCROLLBAR"),//ClassName, ... |
Сообщ.
#13
,
|
|
|
Не, ты говоришь про другое, у штатных скролбаров рисуемых окном при стилях WS_HSCROLL/WS_VSCROLL хэндла нет, стало быть:
1. у них нет оконной процедуры в которой можно перехватить WM_PAINT 2. потому что они рисуются на WM_NCPAINT |
Сообщ.
#14
,
|
|
|
Вот, для демонстрации я выбрал из исходников Windows все требуемые модули, чтобы показать как все устроено.
Начинается все с модуля dwp.c - он содержит в себе DefWindowProc для всех окон. нас интересует xxxDefWindowProc() в части WM_NCPAINT, где мы видим вызов xxxDrawWindowFrame() Теперь переходим в модуль drawfrm.c В процедуре xxxDrawWindowFrame() видим отрисовку бордюров окна, при необходимости заголовка формы и сайзбокса, а в самом конце вызовы xxxDrawScrollBar по одному на вертикальный и горизонтальный. Замечу - все это происходит на момент обработки WM_NCPAINT Ну и в заключение переходим в модуль sbctl.c где реализована сама работа со скролом, причем в режиме как самостоятельного контрола, так и части фрейма окна (о чем наглядно говорят коментарии, да и по коду видно). Т.е. по сути скролбокс при выставленных стилях WS_HSCROLL/WS_VSCROLL это не более чем красивая картинка размещенная на NC области окна. Прикреплённый файлDrawScrollBars.zip (40,23 Кбайт, скачиваний: 246) |