На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Как рисовать в неклиентской области компонента, поверх скроллбара?
    Добрый день!

    Подскажите пожалуйста, как можно рисовать на скроллбаре, например в TMemo?

    Добавлено
    Про WM_NCPAINT я в курсе, но рисовать поверх скроллбара не получается, все рисуется под ним.
      Рисутся не под ним, просто перезатирается самим скролом. Проще рисовать скрол полностью самому, отключив штатный и выделив под него место через WM_NCCALCSIZE
        Rouse_, не могли бы вы привести небольшой пример? Полностью делать, разумеется, не надо, а просто базовый шаблон, который можно взять за основу?
          Цитата estra @
          Про WM_NCPAINT я в курсе, но рисовать поверх скроллбара не получается, все рисуется под ним.

          Теоретически можно, но можно ли это в компоненте Delphi возможностями Delphi - не известно.
          ---
          Технология такая - делаем саб-классинг контрола (перехватываем его оконную процедуру).
          Разрешаем при этом работать оригинальной оконной процедуре контрола.
          После того, как отработает WM_PAINT оригинальной оконной процедуры,
          дорисуем на поверхности контрола что-нибудь ещё.
          Такое я делал, работало устойчиво, но на WINAPI (c++).
            ЫукпШ увы с VCL такое не проходит.
              Цитата estra @
              увы с VCL такое не проходит.

              почему ?? В обработчике WM_PAINT сначала вызываешь inherited, потом делаешь, что хочешь. Должно работать
                Цитата jack128 @
                почему ??


                Потому что скролл перезатирает все, рисуясь поверх всего нарисованного.
                Думаю подход предложенный _Rouse в данном случае будет самым правильным решением.
                  Цитата estra @
                  не могли бы вы привести небольшой пример?

                  Ну вот основу вот тут можешь подсмотреть. По такому принципу разные скины пишутся.
                  https://stackoverflow.com/questions/3753190...bar-delphi?rq=1
                    Rouse_, спасибо, самое то! Уже начал экспериментировать, посмотрим что получится...
                      Цитата estra @
                      Потому что скролл перезатирает все, рисуясь поверх всего нарисованного.

                      Эм, ты сказал, что именно в VCL такое не прокатывает. Типа в WinApi - оно будет работать. Вот мне и интересно где тут ограничение именно VCL? Перехват WM_PAINT - это полный аналог, того что предлагал
                      ЫукпШ (насколько я знаю)
                        А какое отношение WM_PAINT имеет к NC области, к которой собственно и относится скроллбар? :)))
                          Цитата Rouse_ @
                          А какое отношение WM_PAINT имеет к NC области, к которой собственно и относится скроллбар? :)))

                          Скролл-бар - это такой же контрол, как и все остальные.
                          У него есть хэндл и его оконная процедура обрабатывает
                          WM_PAINT. А кто ещё, интересно, обновляет изображение
                          контрола ?
                          Просто бывают составные контролы, включающие в себя
                          несколько стандартных - комбо-бокс, например.
                          ---
                          Если мы хотим дорисовывать на поверхности контрола, значит
                          мы должны перехватить его оконную процедуру.
                          И обработать это сообщение после действий его
                          оригинальной процедуры.
                          ---
                          Возможно, это уже сделано средствами используемой библиотеки.
                          И тогда надо просто знать, как этим пользоваться.
                          Возможно, сама библиотека так написана, чтобы препятствовать
                          этим меропрятиям. Это тоже надо знать.
                          Если возникли какие-то трудно преодолимые трудности с библиотекой,
                          можно создать скролл-бар самостоятельно, как отдельный контрол:
                          ExpandedWrap disabled
                                hwndWin = CreateWindowEx (
                                              styleEx,
                                              _T("SCROLLBAR"),//ClassName,
                            ...
                          Сообщение отредактировано: ЫукпШ -
                            Не, ты говоришь про другое, у штатных скролбаров рисуемых окном при стилях WS_HSCROLL/WS_VSCROLL хэндла нет, стало быть:
                            1. у них нет оконной процедуры в которой можно перехватить WM_PAINT
                            2. потому что они рисуются на WM_NCPAINT :)
                              Вот, для демонстрации я выбрал из исходников 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)
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0466 ]   [ 18 queries used ]   [ Generated: 28.03.24, 08:14 GMT ]