На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
  
> Как узнать цвет фона владельца компонента?
    Чтобы отрисовать нужный уже свой фон, чтобы он не отличался от фона владельца. Вопрос возник в связи вот с этим компонентом CheckBoxX - http://www.antonn.ru/index.php?s_id=09ab1c...401%7C425%7C427

    Если посмотреть на процедуру Paint, то можно увидеть что там отрисовывается только сам чекбоксик и текст справа, а фон (то есть то, что например между чекбоксом и его Caption) оставлено на волю судьбе. Что будет - то будет.

    Я подумал, что можно воткнуть в начало процедуры нечто вроде:

    Rect:= GetClientRect;
    Canvas.Brush.Color:= xxxxxx;
    Canvas.fillRect(Rect);

    Только нужно как-то xxxxx узнать.

    Хелп.
    Сообщение отредактировано: POP -
      xxxxx


      ExpandedWrap disabled
        type TPeekAtControl = class(TControl)
          public property Color;
          end;
         
        TPeekAtControl(Parent).Color


      но фон не обязательно сплошной цвет там может быть и TImage

      Добавлено
      Вообще мне кажется что в случае с TCheckBoxX


      xxxxxx надо заменить просто на Color
        Цитата Frees @
        TPeekAtControl(Parent).Color


        Теоретически эта штука сработала. PS. а что, в Paint как-то то же самое не сделать, только свойство Color переопределять?


        По делу:

        Кажись я не с того боку зашел, компонент лежит на PageControl, который визуально меняет свой цвет при смене темы (на белый), а само свойство Color не меняется, как было BtnFace так и осталось. Фон чекбокса под текущий цвет родителя не подделывается, у него "настоящий" BtnFace рисуется.

        Причем, если взять тот же TLabel, то у него фон вполне себе под измененный "тЕмный" подстраивается.

        Попробовал выдрал весь код из TLabel до отрисовки текста, там он как-раз проверяет включенность темы и затушевывает фон FillRect`ом. Но почему-то для CheckBoxX это не помогло.

        Есть идеи какие-нибудь?

        По ThemesServices как-то мало инфы, в справках вообще ничего нет.
          Цитата POP @
          Если посмотреть на процедуру Paint, то можно увидеть что там отрисовывается только сам чекбоксик и текст справа, а фон (то есть то, что например между чекбоксом и его Caption) оставлено на волю судьбе. Что будет - то будет

          Не "на волю судьбе", т.к. по умолчанию у TCustomControl во-первых, не установлен стиль csOpaque в ControStyle (значит отрисовка его фона - забота парента), во-вторых, установлено св-во ParentColor:=true (значит фон TControl.Color будет соотв-ть фону парента, и, более того, можно еще установить св-во ParentBackground:=true для отрисовки тем XP при подключенном манифесте).
          Поэтому фон TCheckBoxX и так должен соответствовать паренту, за исключением фона надписи, поскольку корявая реализация TCheckBoxX зачем-то переопределяет кучу свойств TControl, включая и Color, и тем самым скрывает доступ к свойствам TControl.Color, Font и т.п. Соотв-но можно просто выкинуть поле fColor, заменить ссылки на него на просто Color и оставить только property Color; - как опубликованное родительского св-во (ну и ParentColor и ParentBackground добавить заодно)
          Сообщение отредактировано: leo -
            Цитата leo @
            более того, можно еще установить св-во ParentBackground:=true для отрисовки тем XP при подключенном манифесте).
            Поэтому фон TCheckBoxX и так должен соответствовать паренту, за исключением фона надписи


            А я вот такую фишку не пойму: почему при смене темы визуально цвет фона родителя меняется (напрм. PageControl), а код цвета нет? То есть как был BtnFace так и остался.

            Установка ParentBackGround:= true устанавливает фон правильно, "новый BtnFace", а вот установка ParentColor для отсрисовки того же фона под Caption результата не дает, она отрисовывает "нормальный BtnFace", беcтемный который.

            Причем, если использовать:

            type TPeekAtControl = class(TControl)
            public property Color;
            end;

            TPeekAtControl(Parent).Color

            для самостоятельной отрисовки фона, то отрисуется "старый-нормальный-BtnFace", а не реальный, который сейчас нарисован на PageCotnrol c темами (белый который).

            Почему так?
              Цитата POP @
              А я вот такую фишку не пойму: почему при смене темы визуально цвет фона родителя меняется (напрм. PageControl), а код цвета нет?

              При включенных темах св-во TControl.Color просто не используется, соотв-но и не изменяется при переключении темы

              Добавлено
              PS: При включенных темах фон рисуется не простым FillRect, а виндовыми функциями DrawThemeBackground или DrawThemeParentBackground, в которые никакой цвет не передается, т.к. он определяется текущей темой. В дельфях эти функции вызываются через обертку ThemeServices:
              ExpandedWrap disabled
                procedure TWinControl.WMEraseBkgnd(var Message: TWMEraseBkgnd);
                begin
                   with ThemeServices do
                     if ThemesEnabled and Assigned(Parent) and (csParentBackground in FControlStyle) then
                     begin
                       { Get the parent to draw its background into the control's background. }
                       DrawParentBackground(Handle, Message.DC, nil, False); //<---
                     end
                     else
                     begin
                       { Only erase background if we're not doublebuffering or painting to memory. }
                       if not FDoubleBuffered or (TMessage(Message).wParam = TMessage(Message).lParam) then
                         FillRect(Message.DC, ClientRect, FBrush.Handle);  //<---
                     end;
                   Message.Result := 1;
                end;
                Цитата leo @
                При включенных темах св-во TControl.Color просто не используется, соотв-но и не изменяется при переключении темы


                Точно, стандартный Чекбокс при включенных темах перестает реагировать на изменение Color. А свой вопрос я решил просто - нужно отрисовывать Caption c прозрачной кистью, тогда не нужно искать правильный "темный" цвет.


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

                ComboxBox при BevelKind:= bkFlat перестает реагировать на смену темы, то есть без стилей остается. Захотелось мне это дело пофиксить, для этого я создал потомка от TComboBox c целью просто в переопределенном конструкторе проверять, если темы есть, то менять bkFlat на bkNone, тогда стили появляются.

                Но не тут-то было, не работает ничего. А вот если воткнуть эту проверку например в переопределенный DropDown, тогда по раскрытию списка стиль появляется.

                То есть настройки BevelKind:= bkFlat установленные для компонента в Инпекторе Объектов как-то "перебивают" настройки, которые я делаю в конструкторе. В какой момент они их перебивают? Мне логика эта компонентная непонятна.
                  Цитата POP @
                  То есть настройки BevelKind:= bkFlat установленные для компонента в Инпекторе Объектов как-то "перебивают" настройки, которые я делаю в конструкторе. В какой момент они их перебивают? Мне логика эта компонентная непонятна

                  Обычная нормальная логика - сначала компонент создается вызовом его конструктора, а затем уже устанавливаются его свойства, заданные в дизайне и сохраненные в dfm-ресурсе формы.
                  Поэтому, если нужно что-то изменить уже после инициализации компонента из dfm, то делать это нужно в методе Loaded, который вызывается после того, как все компоненты формы созданы и проинициализированы
                  Сообщение отредактировано: leo -
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0431 ]   [ 17 queries used ]   [ Generated: 19.04.24, 17:36 GMT ]