Как надежно менять цвет текста подсказки в RadioButton ?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alex2013 »

Вообщем пока сделал как-то так.
Изображение
(Работает, и даже масштабирование (причем исключительно при перезапуске программы ) только пунктирную рамочку выделения непонятно почему сбивает по ширине )
Но сделано это на редкость кондово ( просто "нарисовал" ТLabel поверх RadioButton подобрав шаг смещения "в ручную" )
В принципе в этом не было бы ничего страшного если бы я использовал это фокус на "статической форме", но проблема в том, что форма заполняется динамически.
Так что ни черт ни бог не знает, что там будут за настройки ОС и какие шрифты и как это отразится на контролах созданных динамически . ( Разумеется я использую Font.GetTextHeight и т.п. но как показвает практика этого бывает недостаточно)
В общем может у кого-то хотя-бы какие-то идеи есть? Бо у меня они определенно закончились .... :roll:
Зы
Попытки ловить WM_CtlColor и WM_CtlColorStatic ничего не дали.
Последний раз редактировалось Alex2013 13.05.2024 21:13:50, всего редактировалось 2 раза.
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 836
Зарегистрирован: 20.07.2013 01:04:30

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Sharfik »

Ничего непонятно :)
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alex2013 »

Sharfik писал(а):Ничего непонятно :)
Все просто! Есть RadioButton стандартное MyRadioButton.Font. Color:= clRed; не работает со времен Дэльфи 7 .
(Что в дельфи что в лазарусе ) И как результат буквы "подсказки" всегда выводятся черным цветом что для темного фона фатально.Как-то обойти это дело как случае CheckBox найдя готовое решение не получилось. Нашел временную затычку : "нарисовать" текст поверх текущего . (Просто вставил ТLabel по заданным координатам бо мучать класс ТRadioButton прикрывая перерисовку как бы не кривее и точно будет мнение удобно в отладке . )

Есть чуть более простой путь перекрытие обработчика WM_CtlColorХХХХ , WM_CtlColorStatic ( и тому подобных сообщений ) в форме но тут он не сработал . (WM_CTLCOLORBTN вроде есть но почему-то не вызывается хотя возможно я где-то что-то напутал )
Зы
Вся беда этой штуки в том что это стандартный элемент винды за отрисовку которого отвечает сама система, а LCL просто создает оболочку вокруг стандартного интерфейса WinAPI.

Временный код

Код: Выделить всё

  Lst:=Tlist.Create;
  EI:=Sl.GetEnumerator;

   While EI.MoveNext do
       begin
        CControl:= TRadioButton.Create(SubP);
        CControl.Align:=alBottom;CControl.Font.Color:=clWhite;
        S1:=EI.GetCurrent; FillChar(s1[1],s1.Length,'_');
        TRadioButton(CControl).Caption:=S1+'__';
        TRadioButton(CControl).Alignment:=taLeftJustify;
        SubP.InsertControl(CControl);

      L_RB:= TLabel.Create(SubP);
      L_RB.Caption:=' '+EI.GetCurrent;
      L_RB.Font.Color:=clWhite;
      L_RB.Top:=3+(SubP.ControlCount-1)*(3+P.Font.GetTextHeight('|')); //! Вот эта строчка самая "подозрительная".
      L_RB.Left:=1;
      Lst.add(L_RB);
    end;
    Ei.Free;

    //--------------------
    EL:=Lst.GetEnumerator;
    While EL.MoveNext do
     SubP.InsertControl(Tlabel(EL.GetCurrent));
    El.Free;
    Lst.Free;
///      
Последний раз редактировалось Alex2013 29.03.2024 09:34:28, всего редактировалось 1 раз.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Снег Север »

Найти замену в библиотеках компонентах или писать собственный компонент. Ваш Кэп, не благодарите.
Аватара пользователя
Alexander
энтузиаст
Сообщения: 864
Зарегистрирован: 18.12.2005 18:10:00
Откуда: оттуда
Контактная информация:

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alexander »

Скорее всего это называется не подсказка (hint), а лейбл (наклейка, надпись).
Вся беда этой штуки в том что это стандартный элемент винды за отрисовку которого отвечает сама система, а LCL просто создает оболочку вокруг стандартного интерфейса WinAPI.
Скорее всего здесь заключается неявная ошибка. До какой-то степени это так, но не в целом. Часть функций (каркас) конечно задействуются, но основная масса собственная отрисовка. Для того чтобы понять это, нужно понять методом исключения, что Лазарус скорее "Делфи для Линукс", а здесь тоже есть Паскаль, есть Лазарус, в нём есть RadioButton, есть Label, а WinAPI нет и всё работает. То есть странно именно для Лазаруса искать эту функцию в WinAPI.
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alex2013 »

Снег Север писал(а):Найти замену в библиотеках компонентах или писать собственный компонент. Ваш Кэп, не благодарите.
:D
Зы
Гораздо более удивительно в сети так мало инфы на данную тему . Понятно что RadioButton применятся не так уж часто и обычно на отдельной панельке но все-же не настолько же редко что бы не было хотя-бы обсуждения!
Найти замену наверное можно, но как это было например со скроллбаром, в "левых" компонентах часто заметно не хватает функционала. На писать или "эмулировать" свой компонет имеет смысл если задача в принципе не имеет другого решения и/или проблема возникает достаточно часто .

Добавлено спустя 8 минут 11 секунд:
Alexander писал(а):Скорее всего это называется не подсказка (hint), а лейбл (наклейка, надпись).
Вся беда этой штуки в том что это стандартный элемент винды за отрисовку которого отвечает сама система, а LCL просто создает оболочку вокруг стандартного интерфейса WinAPI.
Скорее всего здесь заключается неявная ошибка. До какой-то степени это так, но не в целом. Часть функций (каркас) конечно задействуются, но основная масса собственная отрисовка. Для того чтобы понять это, нужно понять методом исключения, что Лазарус скорее "Делфи для Линукс", а здесь тоже есть Паскаль, есть Лазарус, в нём есть RadioButton, есть Label, а WinAPI нет и всё работает. То есть странно именно для Лазаруса искать эту функцию в WinAPI.
1 В принципе согласен "подсказка" это hint а тут скорре "описание варианта выбора" но лейба тоже пойдет.
2 Читал что проблемы началась после того как в Дельфи научили использовать манифест. ( в современным программах он включен по умолчанию )
3 WinAPI в лазарусе навалом( функционал WinAPI доступен почти полностью) . Другое дело что юзать его та еще "попаболь" да и проблемы вылезают те же самые . ( типа невозможности свободно менять цвет кнопки )

Добавлено спустя 1 час 3 минуты 32 секунды:
Алиса Яндексовна подсказала...
RadioButton1.Style := RadioButton1.Style + [tfFlat]
Это сделает радиокнопку плоской, без градиента и прочего, но зато позволит менять цвет текста.
Надо проверить.
... Не работает!
Последний раз редактировалось Alex2013 29.03.2024 11:56:00, всего редактировалось 1 раз.
Аватара пользователя
Alexander
энтузиаст
Сообщения: 864
Зарегистрирован: 18.12.2005 18:10:00
Откуда: оттуда
Контактная информация:

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alexander »

А SetTextColor не срабатывает ?

В старину я делал так:

Код: Выделить всё

 DC := GetWindowDC(hwnd); {WDC := }BeginPaint(hwnd, p);

 if app.tun.mute or app.tun.NoAct then BkColor := colr_rd else BkColor := colr_db;
  if app.tun.mute or app.tun.NoAct then BColor := hb_rd else BColor := hb_db;

 r.Left := 0; r.Right := FWidth; r.Top := 0; r.Bottom := FHeight;

 FillRect(DC, r, BColor);

 SelectObject(DC, hf_clock);

 if app.orgtodaycount > 0 then
    SetTextColor(DC, colr_white) else
    SetTextColor(DC, colr_yl);
 SetBkColor(dc, BkColor);
 SetTextAlign(dc, TA_CENTER);

      EndPaint(hwnd, p);
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alex2013 »

Оказывается "Алиса права"(тм) правда пришлось творчески "допилить её совет напильником" .
Изображение
Единственный недостаток чуть меньшая точка отмечающая выделение. :idea:
Но это уже дело десятое.
Добавлено спустя 7 минут 37 секунд:
Подключаю модуль.
Uses UxTheme,...
Заполнение...

Код: Выделить всё

...
Var
СControl:TWinControl;
SubP:TPanel;
Sl:TSrtringList;
EI : TStringsEnumerator;  
...
   EI:=sl.GetEnumerator;
   While EI.MoveNext do
       begin
        CControl:= TRadioButton.Create(SubP);
        C11:=CControl;// Запоминаю какой нибудь TRadioButton
        CControl.Align:=alBottom;
        CControl.Font.Color:=clLime;//clWhite;
        TRadioButton(CControl).Caption:=ei.Current;
        TRadioButton(CControl).Alignment:=taLeftJustify;
        SubP.InsertControl(CControl);
    end;
    Ei.Free;
...
А потом делаю вот такой фокус ...

Код: Выделить всё

// FormActivate нужен чтобы были "живые" Handle  
 //UxTheme.SetWindowTheme работает только с активными контролами .    
procedure TForm1.FormActivate(Sender: TObject);
begin
With TPanel(c11.Owner).GetEnumeratorControls do
 begin
 while MoveNext do
   if Current.ClassType=TRadioButton then
   UxTheme.SetWindowTheme(TWinControl(Current).Handle,nil,'');
 free;
 end;
end;
Разумеется это просто упрощенный тест который работает только при одном наборе RadioButton
И вообще без многих проверок но как пример вполне годится
( Суть в том что SetWindowTheme кроме прочего насильно включает "плоский" режим)

Добавлено спустя 34 минуты 29 секунд:
Alexander писал(а):А SetTextColor не срабатывает ?

В старину я делал так:

Код: Выделить всё

 DC := GetWindowDC(hwnd); {WDC := }BeginPaint(hwnd, p);

 if app.tun.mute or app.tun.NoAct then BkColor := colr_rd else BkColor := colr_db;
  if app.tun.mute or app.tun.NoAct then BColor := hb_rd else BColor := hb_db;

 r.Left := 0; r.Right := FWidth; r.Top := 0; r.Bottom := FHeight;

 FillRect(DC, r, BColor);

 SelectObject(DC, hf_clock);

 if app.orgtodaycount > 0 then
    SetTextColor(DC, colr_white) else
    SetTextColor(DC, colr_yl);
 SetBkColor(dc, BkColor);
 SetTextAlign(dc, TA_CENTER);

      EndPaint(hwnd, p);
Это разумеется тоже вариант, но он "на несколько этажей ниже" и я до него просто не добрался ...
(ИМХО Почти всегда если есть возможность лучше не лезть в перерисовку через WinAPI, а то внезапно вылезают кучи проблем с кодировкой,видимостью, центровкой и еще черт знает чем ... )
Аватара пользователя
Alexander
энтузиаст
Сообщения: 864
Зарегистрирован: 18.12.2005 18:10:00
Откуда: оттуда
Контактная информация:

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alexander »

Ну да, так и есть. Тогда может быть написать багрепорт разработчикам Лазаруса да и всё ?
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alex2013 »

Непередаваемое ощущение сломанного тессеракта... :wink: :idea:
(Зато без лишних списков которые того гляди запутаются при повтором чтении )
Изображение

Это как-бы исправленный код для возможности пропатчить несколько динамически созданных списков RadioButton .
(Разумеется все привязано к конкретной программе но сама по себе идея вполне масштабируется )

Код: Выделить всё

E:=ScrollBox1.GetEnumeratorControls;// Левел 1  ( обычный ScrollBox)
while E.MoveNext do
  begin
  C1:=TPanel(E.Current);  If TPanel(C1).ControlCount>1 then // Левел 2  Панель параметра 
 begin
 C1:=TPanel(TPanel(C1).Controls[1]);//Левел 3  панель внутри панели   
//(возможно что это слабое место (нумерация контролов не очень надежная штука ), но пока вроде работает )
   
If (TPanel(C1).ControlCount>0) And (TPanel(C1.Controls[0]).ClassType=TRadioButton) then

 With TPanel(c1).GetEnumeratorControls do // Левел 4  собственно список RadioButton 
//(наконец врубился  фишку с GetEnumerator оказывается их можно вообще без переменной использовать )
 begin
 while MoveNext do UxTheme.SetWindowTheme(TWinControl(Current).Handle,nil,'');
 free;
 end;
 end
end;
E.Free;
(Интересно можно ли это "чудовище" немного оптимизировать ? )

Добавлено спустя 9 минут 4 секунды:
Alexander писал(а):Ну да, так и есть. Тогда может быть написать багрепорт разработчикам Лазаруса да и всё ?
Не думаю что это вина Лазаруса и Дельфи ... Это товарищи мелкомягкие мудрят.
( При включении "плоского режима" все работает как часы так что LCL все делает верно )
Зы
Интересно можно ли принудительно отключить манифест? Сдается мне что в этом случае многое станет работать как надо !
Зы Зы
Замечен но продолен странный глюк (перестала показываться рамка выбора RadioButton )
Ну поскольку я и так хотел поравить фокус при старте то это ерунда легко задвинулась .
Но что это было не понял. :idea:
Впрочем это винда где периодически возможно почти ВСЕ !
Последний раз редактировалось Alex2013 01.04.2024 08:53:17, всего редактировалось 4 раза.
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 836
Зарегистрирован: 20.07.2013 01:04:30

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Sharfik »

Alex2013 писал(а):Гораздо более удивительно в сети так мало инфы на данную тему
Потому что нормальные люди цвета не меняют. Я вот стал тестировать программу в режиме повышенной контрасности и понял что у меня все работает, а RXDBGrix (к примеру) в строке фильтр срать хотел на системные настройки, и что у человека могут быть проблемы с глазами - тупо белое поле.
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alex2013 »

Sharfik писал(а):
Alex2013 писал(а):Гораздо более удивительно в сети так мало инфы на данную тему
Потому что нормальные люди цвета не меняют. Я вот стал тестировать программу в режиме повышенной контрасности и понял что у меня все работает, а RXDBGrix (к примеру) в строке фильтр срать хотел на системные настройки, и что у человека могут быть проблемы с глазами - тупо белое поле.
Только почему то большая часть современных программ имеет четко выраженные цветовой стили.
(Часть этого идет от моды водимой ОС но значительная часть обращается с цветами довольно резко )
Кроме того я пишу не про отсутствие обсуждений настроек цветов вообще (этого сколько угодно ) а конкретно о RadioButton.
Зы
( И вообще в 90-х были "демократы" сейчас тенденция "дерьмократии" с посылом "ЕШЬ ЧТО ДАЮТ ЦУКА!" Я такой: :shock: "Зачем есть-же выбор!", а мне в ответ... "Все едят и ты потребляй..." ...и нафига "совок" спрашивается с такими романсами развалили? Там хоть обоснование пытались давать... типа "пейте дети молоко будете здоровы"! А тут ... "Массовая контркультура" Оксюморон... Тьфу! Одним словом! )

Ладно извини,"Остапа немного понесло!"
Зы Зы
Режим повышенной контрастности и все прочие должно по идее включается специальной настройки "стандартные цвета" отключающей все "свистелки мигалки" под корень . А ценителям авторских и нестандартных настроек нужны темы и полная настройка цветов.
Конкретно в этом случае я пытаюсь скопировать определенный стиль который был у другой программы некоторую я в меру сил равняюсь и если бы подобный интерфейс получался-бы стандартными средствами я бы был бы этому только рад . Но увы в лазарусе нет нормальной темной-темы (и много чего еще) так а что приходится в очередной раз изобретать велосипед.

Например меня тут недавно как-то случайно хвалили за настраиваемую геометрию панелек с имитаций "однооконного интерфейса " так честно говоря мне стыдно было потому, что на эту ерунду ушли почти что "простыни кода" описывающего реакцию каждой финтифлюшки и их взаимодействие, да по идее это все автоматом должно было работать! Но чего нет того нет.. :idea:
(Впрочем почти наверняка кто нибудь более умелый добился бы лучшего результата более правильным путем ... так что увы "маемо те що маемо"! :idea: )
Последний раз редактировалось Alex2013 13.05.2024 21:21:03, всего редактировалось 1 раз.
Аватара пользователя
Alexander
энтузиаст
Сообщения: 864
Зарегистрирован: 18.12.2005 18:10:00
Откуда: оттуда
Контактная информация:

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alexander »

Интересно можно ли принудительно отключить манифест?
Это не оно ?

https://forum.lazarus.freepascal.org/in ... ic=26894.0
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Alex2013 »

Alexander писал(а):
Интересно можно ли принудительно отключить манифест?
Это не оно ?

https://forum.lazarus.freepascal.org/in ... ic=26894.0
"Оно" но с отладчиком действительно беда...

В собранный "без манифеста" код из под лазаруса вообще не запускается (даже без отладки).
А так действительно помогает.
Но походу если темы манифеста действительно работают то стоит копать именно их. :idea:
------------------------------------------------------------
Какая то левая тема
https://gist.github.com/cpicanco/525bd3 ... 58d6fe3531
получить цвет фона из темы. ()
http://freepascal.ru/forum/viewtopic.ph ... me#p104881

Как покрасить ProgressBar (Со скролл бар вроде не работает но это неточно )

Код: Выделить всё

const
  PBM_SETBARCOLOR = WM_USER + 9;   

  UxTheme.SetWindowTheme(ProgressBar.Handle, nil, '');
  ProgressBar.Brush.Color:= clRed;
  SendMessage(ProgressBar.Handle, PBM_SETBARCOLOR, 0, clRed);
Подозрительный патчер... как я понял патчит uxtheme.dll
https://mhoefs.eu/software_uxtheme.php?lang=en

Зы
Skins for Lazarus
https://github.com/Onur2x/onurcomp
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 836
Зарегистрирован: 20.07.2013 01:04:30

Re: Как надежно менять цвет текста подсказки в RadioButton ?

Сообщение Sharfik »

Alex2013 писал(а):Режим повышенной контрастности и все прочие должно по идее включается специальной настройки "стандартные цвета" отключающей все "свистелки мигалки" под корень . А ценителям авторских и нестандартных настроек нужны темы и полная настройка цветов.
Если программа для узкого круга - что угодно, если программа на широкий круг - надо учитывать потребности людей с проблемами зрения. Вот я к чему. И для нас самый дешевый по времени вариант - стандартные темы ОС.
Ставил тут Linux с KDE и шкуркой как будто Vista. Наиболее похожий просто вариант на Windows для пожилого человека. Так при масштабировании 125% эта шняга в заголовке начала глючить :((

По проблеме - только сторонние компоненты изучать. Можно в Typhon покопать что там есть, и если кто в лазарус перекинуть компоненты.
Ответить