Re: Как изменить цвет кнопки?
От: okon  
Дата: 17.10.19 02:04
Оценка: +1 -2
ЕМ>Все действительно настолько плохо, или я где-то чего не догоняю?

Потом народ спрашивает а чем WPF лучше.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[9]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 25.11.19 10:59
Оценка: 1 (1) +1
Здравствуйте, CEMb, Вы писали:

CEM>О, я вспомнил, как быстро и легко(ну, вроде) подкрасить кнопку:


Спасибо! Однако, перечисленными способами выходит слишком много суеты, сопряженной с риском что-то испортить в навороченных визуальных темах. Красная рамка вокруг кнопки и в глаза бросается (вряд ли в каких-то темах будет ярко-красный фон, да и в этом случае можно поменять цвет на контрастный), и порождает желание навести на кнопку курсор, а там уж ToolTip подскажет, что и как.
Re[3]: Как изменить цвет кнопки?
От: wildwind Россия  
Дата: 17.10.19 10:19
Оценка: +2
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Грустно. По сути, мне в некоторых случаях нужно просто выделить кнопку, чтобы указать на ситуацию, в которой ее требуется нажать. Тогда придется вешать значок, рисовать рамку или еще что-то подобное...


Вообще хорошим тоном считается не полагаться только на цвет. Так что лучше нарисуй рамку.
Re[5]: Как изменить цвет кнопки?
От: qaz77  
Дата: 18.10.19 09:26
Оценка: 10 (1)
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Я в своем минимализме как-то и забыл, что, кроме классического серого фона, существуют еще и хитрораскрашенные темы.

Для рисования в контексте текущей визуальной темы есть функция DrawThemeBackground и ее компаньоны. Также надо учитывать всякие специальные состояния: default, hot и т.п. И цвет фона там может быть не один, а градиенты или более хитрые текстуры.

Вот пример использования из MSDN:
if (_hTheme)
{
  if (IsThemeBackgroundPartiallyTransparent(_hTheme, BP_PUSHBUTTON, _iStateId))
  {
    DrawThemeParentBackground(_hwnd, hdcPaint, prcPaint);
  }

  DrawThemeBackground(_hTheme,
                    hdcPaint,
                    BP_PUSHBUTTON,
                    _iStateId,
                    &rcClient,
                    prcPaint);
}


Печаль в том, что для классической темы это как раз не работает.
Надо проверять активность темы для клиентской части окон текущего процесса и, если темы отключены, рисовать через древний DrawFrameControl.
Re[10]: Как изменить цвет кнопки?
От: CEMb  
Дата: 25.11.19 17:57
Оценка: 3 (1)
Здравствуйте, Carc, Вы писали:

C>Не слишком ли для задачи "просто привлечь внимание"!?!

Ну для меня этот алгоритм простой, я много с этим работал.

C> Да еще с косяками нюансами в сторону! Хренакс, с кнопыч перестал и вовсе реагировать на мыша?

C>а) Нюанс са-а-а-а-авсем не очевидный.
Не, на самом деле оно будет реагировать. Обычные кнопки с иконками делают картинке pop up, когда мышкой наводишься. Тут будет то же самое.

C>б) Возникнуть он может банальным и таким же малоочевидным косяком, вроде сбоя в районе восстановления исходного состояния. Т.е. не просто на время на мышь перестанет откликаться, а и вовсе навсегда…


C>в) Ну и к тому же еще "битмапить по черному", а это значит вперед — в режим ядра…

Нене какого такого ядра? Это же BM_SETIMAGE

C>г) Ну и вообще… Как там насчет Бритвы нашего Оккамы? Не стоит множить сущности без надобности…

Согласен. Я просто вспомнил ещё один способ. Не, кстати, вот ты смеёшься, а я когда скинил промышленный софт, мой манагер принёс новое MFC, которое умело "скинить кнопки просто". И была идея выкинуть все мои разработки и взять готовое. При внимательно рассмотрении оказалось что там ownerdraw.

C>Я б поостерегся… Уж больно нарваться можно с таким кодом. Ни одна, и не две недели с отладчиком наперевес обеспечены.

Ну у меня в этом опыт есть.

C>С той же видимостью\невидимостью контрола\дочернего окна, хоть теоретически можно подстраховаться в стиле LockResource. Какой-нить банальный класс\struct с обязательным параметром HWND в конструкторе, который соответственно в деструкторе восстанавливает видимость окна.

C>В случае сбоя это все равно не спасет. Но хоть что-то…. В случае досрочного завершения функции "блинкования", не нужно хотя бы постоянно помнить, что нужно восстановить видимость контрола.
Да, это тоже хороший вариант
Re[3]: Как изменить цвет кнопки?
От: okon  
Дата: 17.10.19 08:05
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, okon, Вы писали:


O>>Потом народ спрашивает а чем WPF лучше.


ЕМ>А оно лучше?


там цвет кнопки и все остальное , в том числе лейаут контролов, менять ощутимо проще.
Необходимость в использовании сторонних компонент как правило отпадает, кастомные писать получаетя не так сложно и не дорого.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Отредактировано 17.10.2019 8:08 okon . Предыдущая версия . Еще …
Отредактировано 17.10.2019 8:08 okon . Предыдущая версия .
Re[4]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.10.19 10:24
Оценка: +1
Здравствуйте, wildwind, Вы писали:

W>Вообще хорошим тоном считается не полагаться только на цвет. Так что лучше нарисуй рамку.


Я в своем минимализме как-то и забыл, что, кроме классического серого фона, существуют еще и хитрораскрашенные темы.
Re[3]: Как изменить цвет кнопки?
От: qaz77  
Дата: 18.11.19 14:42
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>В случае рамки, как оказалось, и сабклассинг не поможет — WM_PAINT и его производные вызываются только для области самой кнопки.

Способ 1.
Если не трогать саму кнопку, то можно динамически создавать статик нужного размера и цвета.
Через SetWindowPos ставить ему Z-ордер "под кнопкой" и еще добавить стиль clip siblings, чтобы кнопка не мерцала при перерисовке.

Способ 2.
Как предложили уже — использовать не клиентскую область окна.
У стандартной кнопки не клиентская область не используется (в отличие от edit, например).
Чтобы ее задействовать нужно реализовать обработчик WM_NCCALCSIZE, где указать желаемый размер не клиентской области.
В обработчике WM_NCPAINT — залить нужным цветом.
Если состояние кнопки меняется и нужно перерисовать не клиентскую область, то нужно звать SetWindowPos с флагом SWP_FRAMECHANGED.

Способ 2а.
Упрощенный вариант 2. Вместо обработки WM_NCCALCSIZE ставим кнопке стиль WS_EX_CLIENTEDGE и получаем готовую рамку толщиной 2 пикселя.
Заменяем обработчик WM_NCPAINT — вместо рисования "утопленной" рамки, заливаем нужным цветом.
Вместо WS_EX_CLIENTEDGE можно поставить WS_EX_STATICEDGE, тогда будет рамка толщиной 1 пиксель.
С масштабом экрана (non 96 DPI) толщина таких рамок не дружит, если чо.

P.S. Для первого способа в шаблоне диалога надо предусматривать место под статик, а для второго — увеличивать размер самой кнопки,
чтобы текст помещался в клиентскую область.
Re[7]: Как изменить цвет кнопки?
От: qaz77  
Дата: 20.11.19 09:42
Оценка: -1
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Фон может определяться более, чем одной кистью? Я в прошлом варианте применил FrameRgn как раз для того, чтобы рисовать кистью, а кисть добывал из WNDCLASS::hbrBackground.

Все эти hbrBackground, WM_CTLCOLOR и т.п. были актуальны до Win XP.
Тем не менее, они продолжают поддерживаться и могут в каких-то ограниченных сценариях использоваться, когда все прямоугольное и одного цвета.

Для полноценного использования стандартных контролов Windows из commctl32 надо использовать ее 6-ую версию, т.е. добавить соотв. инфу в манифест приложения.
Для их полноценной кастомизации — использовать uxtheme.dll API.
Re[11]: Как изменить цвет кнопки?
От: Carc Россия https://vk.com/gosha_mazov
Дата: 25.11.19 11:30
Оценка: -1
Здравствуйте, Евгений Музыченко, Вы писали:


C>>И потом: вот enum это RVALUE. Причем жесткий такой RVALUE. Здесь не получатся танцы с бубном, вроде const_cast, или взять адрес.


ЕМ>Ну вот разве что. Но подобные ошибки крайне редки, стоит ли против них применять такие приемы?


Стоит! Еще как стоит…
Забыли указать const для нашего UINT. Ну бывает, всяко оно бывает. Стажер правил, все дела. Прогнали тесты, всё зер гут. И забыли. Ибо код-то, тривиальный, ну согласитесь. Кто его потом особо инспектировать будет, работает, и хорошо. Да и ломаться там (вроде бы) нечему.

А потом порефакторили, изменили какой-абстрактный код вовне, который изменит эту переменную с забытой const. И ку-ку… Выявлять этот косяк можно очень долго. Ибо неочевидный он очень. Сам код же явно в стиле MyUtilities, Helpers и.т.д и использоваться может откуда и когда угодно. А проблемы он создаст как раз в вызывающем коде. Ох, как можно потом покопаться, чтобы найти проблему.

И хорошо, если косячить будет через каждую секунду почти везде и всегда. А если в каком-то крайне редком случае, в крайне редкой конфигурации!?!
Aml Pages Home
Re[12]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 25.11.19 16:17
Оценка: -1
Здравствуйте, Carc, Вы писали:

C>Забыли указать const для нашего UINT.

C>А потом порефакторили, изменили какой-абстрактный код вовне, который изменит эту переменную с забытой const.

Сдается мне, что Вы преувеличиваете степень риска. Особенностей синтаксиса/семантики, при которых проблема возникает только при "встречных" ошибках в двух и более местах, найдется немало. Если уж заранее применять меры против гипотетических ситуаций, порожденных подобными "встречными" ошибками, то нужно делать анализ синтаксиса, перечислять все возможные сочетания, и блокировать каждое.
Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 16.10.19 20:39
Оценка:
Сегодня утром приспичило сделать изменение цвета [фона] верхней поверхности кнопки (обычный PUSHBUTTON). Ничего больше менять не нужно — задача вроде бы примитивная донельзя. Однако, сейчас уже поздний вечер, но я в этом вопросе практически не продвинулся, зато успел изрядно охренеть.

Первой мыслью было использовать WM_CTLCOLORBTN. Однако документация утверждает (и это так и есть), что для стилей BS_PUSHBUTTON, BS_DEFPUSHBUTTON и BS_PUSHLIKE возвращаемая кисть игнорируется. Тогда для чего это сообщение шлется кнопкам с этими стилями? Какой в нем может быть практический смысл?

Видел в сети советы использовать WM_CTLCOLORSTATIC, но оно в диалог не присылается.

Следующая идея — WM_NOTIFY/NM_CUSTOMDRAW, которые для обычных кнопок поддерживаются в comctl32.dll, начиная с шестой версии. У меня версия 6.16 (Win7), все сообщения приходят, но никакой реакции на выбор кисти или карандаша, а также на SetBkColor/SetTextColor не вижу. Вставил все это и в PreErase, и в PrePaint — без толку.

Здесь предлагают в обработчике CDDS_PREERASE вызывать FillRect и возвращать CDRF_DODEFAULT, но это гарантированно не работает, поскольку стандартный обработчик тут же перезаливает область. Если вызвать FillRect по CDDS_PREPAINT, то стандартный обработчик затем рисует поверх залитого прямоугольника текст со стандартным фоном, невзирая на вызов SetBkColor.

Я, честно говоря, в полном ауте от того, что столь примитивная задача требует таких изощренных плясок. Что еще остается делать? Можно рисовать самому через WM_DRAWITEM, но это ж из пушки по воробьям. Сабклассить — тоже и громоздко, и грязно. Вызывать на время отрисовки SetSysColors — будут дергаться другие окна, а им это ни к чему?

Все действительно настолько плохо, или я где-то чего не догоняю?
кнопка button pushbutton nm_customdraw цвет фон
Re: Как изменить цвет кнопки?
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 16.10.19 21:37
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Все действительно настолько плохо, или я где-то чего не догоняю?


Давно-давно, когда операционки были маленькими, процессоры — 32-битными, а памяти хватало не только на запуск браузера, заинтересовался я, как можно сделать кнопку с картинкой при включённых стилях WinXP. MFC-шный CButton::SetIcon (вроде бы, опирается на BM_SETIMAGE) картиночку-то добавлял, но саму кнопку превращал в прямоугольную классическую, что выглядело, мягко говоря, неуместно. В итоге мне тогда удалось нагуглить лишь один рабочий вариант, который наследовался от класса CButton, переопределял OnPaint, вызывал родительскую версию и поверх полученного изображения кнопки дорисовывал картинку своими силами.

Исходя из этого, есть у меня сильное подозрение, что стандартные контролы, вид которых управляется темой, нельзя просто так взять и поменять. Конечно, остаётся ещё вероятность, что существуют какие-то хитрые вызовы; или что тогда их не было, а теперь появились (всё-таки много времени прошло)…
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re: Как изменить цвет кнопки?
От: small_cat Россия  
Дата: 17.10.19 05:22
Оценка:
Доброго времени.

Нет, это все не работает, ибо стандартные контролы.
Можно время не тратить, а сразу искать стороннее/писать своё.
- Простите, профессор, не пса, а когда он уже был человеком.
— То-есть он говорил? Это еще не значит быть человеком. (с) Булгаков
Re[2]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.10.19 07:59
Оценка:
Здравствуйте, okon, Вы писали:

O>Потом народ спрашивает а чем WPF лучше.


А оно лучше?
Re[2]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.10.19 08:01
Оценка:
Здравствуйте, small_cat, Вы писали:

_>Нет, это все не работает, ибо стандартные контролы.


Грустно. По сути, мне в некоторых случаях нужно просто выделить кнопку, чтобы указать на ситуацию, в которой ее требуется нажать. Тогда придется вешать значок, рисовать рамку или еще что-то подобное...
Re[4]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.10.19 09:07
Оценка:
Здравствуйте, okon, Вы писали:

O>там цвет кнопки и все остальное , в том числе лейаут контролов, менять ощутимо проще.

O>Необходимость в использовании сторонних компонент как правило отпадает, кастомные писать получаетя не так сложно и не дорого.

Любой фреймворк имеет какие-то ограничения. Поначалу кажется, что все просто, красиво и выразительно, а потом, когда привыкнешь, непременно вылезет какая-нибудь хрень, на борьбу с которой уйдет больше времени, чем было сэкономлено. Я пару раз напарывался, с тех пор опасаюсь.
Re[5]: Как изменить цвет кнопки?
От: okon  
Дата: 17.10.19 09:16
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, okon, Вы писали:


O>>там цвет кнопки и все остальное , в том числе лейаут контролов, менять ощутимо проще.

O>>Необходимость в использовании сторонних компонент как правило отпадает, кастомные писать получаетя не так сложно и не дорого.

ЕМ>Любой фреймворк имеет какие-то ограничения. Поначалу кажется, что все просто, красиво и выразительно, а потом, когда привыкнешь, непременно вылезет какая-нибудь хрень, на борьбу с которой уйдет больше времени, чем было сэкономлено. Я пару раз напарывался, с тех пор опасаюсь.


есть замороченные вещи, но не могу придумать пример который в других UI фреймворках для Windows делается проще.
обычно то что сложно в WPF еще сложнее в других, может я просто плохо знаю WPF и другие фреймворки и не могу придумать пример.
Было бы интересно услышать опыт кто работает с ними много.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[5]: Как изменить цвет кнопки?
От: wildwind Россия  
Дата: 18.10.19 10:23
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Я в своем минимализме как-то и забыл, что, кроме классического серого фона, существуют еще и хитрораскрашенные темы.


Существуют еще и люди с особенностями зрения.
Re[6]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 18.10.19 10:54
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Существуют еще и люди с особенностями зрения.


Ну и как в таких условиях выделить кнопку, чтобы показать, что она имеет основание быть нажатой? Рисовать вокруг нее рамку, плавно меняющую цвет, чтобы ее увидел и каждый дальтоник?
Re[7]: Как изменить цвет кнопки?
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 18.10.19 11:48
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Ну и как в таких условиях выделить кнопку, чтобы показать, что она имеет основание быть нажатой? Рисовать вокруг нее рамку, плавно меняющую цвет, чтобы ее увидел и каждый дальтоник?


А ещё озвучивать процесс, чтобы и слепые могли быть в курсе.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[7]: Как изменить цвет кнопки?
От: wildwind Россия  
Дата: 18.10.19 12:24
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Ну и как в таких условиях выделить кнопку, чтобы показать, что она имеет основание быть нажатой? Рисовать вокруг нее рамку, плавно меняющую цвет, чтобы ее увидел и каждый дальтоник?


Да просто рамки или подчеркивания системного цвета должно быть достаточно.
Но я бы еще подумал, если в данной ситуации нужно нажимать строго определенную кнопку, то может её того... и нажимать программно, не отвлекая пользователя?
Re[7]: Как изменить цвет кнопки?
От: RonWilson Россия  
Дата: 18.10.19 12:31
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, wildwind, Вы писали:


W>>Существуют еще и люди с особенностями зрения.


ЕМ>Ну и как в таких условиях выделить кнопку, чтобы показать, что она имеет основание быть нажатой? Рисовать вокруг нее рамку, плавно меняющую цвет, чтобы ее увидел и каждый дальтоник?


не надо ничего рисовать, просто сделайте пульсирующую кнопку (+- высота и длина по таймеру) с тикающим фоновым звуком
Re[8]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 18.10.19 13:10
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Но я бы еще подумал, если в данной ситуации нужно нажимать строго определенную кнопку, то может её того... и нажимать программно, не отвлекая пользователя?


Не, по этой кнопке открывается одно из окно виндовых настроек. Так-то она просто для удобства, но, если системные настройки неподходящие — надо пользователя навести на мысль, что надо туда заглянуть.
Re: Как изменить цвет кнопки?
От: Pavel Dvorkin Россия  
Дата: 20.10.19 03:10
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

В крайнем случае сабклассинг этой кнопки, свой обработчик WM_PAINT, в нем залить нужной кистью. Должно сработать, ибо не зависит от типа контрола, общий механизм.
With best regards
Pavel Dvorkin
Re[2]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.10.19 10:13
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В крайнем случае сабклассинг этой кнопки, свой обработчик WM_PAINT, в нем залить нужной кистью.


Да это понятно, просто я до последнего полагал, что там должен быть способ делать это без явных извращений.
Re[4]: Как изменить цвет кнопки?
От: Mr.Delphist  
Дата: 22.10.19 13:05
Оценка:
Здравствуйте, okon, Вы писали:

O>там цвет кнопки и все остальное , в том числе лейаут контролов, менять ощутимо проще.


Что неудивительно — весь WPF построен на owner draw. Там и HWND как таковых-то и нету, кроме внешнего контейнера.

O>Необходимость в использовании сторонних компонент как правило отпадает, кастомные писать получаетя не так сложно и не дорого.


Зависит от ситуации, причём сильно. Помнится, при нетривиальной интерактивности, когда контрол (точнее, их группу в листбоксе) надо было перекрашивать исходя из текущих активностей мышки юзера, там начали лезть неиллюзорные уши "Win32 mouse capture API". Но в большинстве ситуаций да, надо отдать должное команде WPF — они запилили весьма достойный фреймворк.
Re: Как изменить цвет кнопки?
От: c-smile Канада http://terrainformatica.com
Дата: 05.11.19 19:34
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Все действительно настолько плохо, или я где-то чего не догоняю?


Кнопки рисуются uxtheme.dll как составное изображение. Нет там background color как такового.

Если нужно выделить как-то выбор то идеологически правильно использовать BS_DEFPUSHBUTTON тип:

https://docs.microsoft.com/en-us/windows/win32/controls/button-types-and-styles#button-types-and-styles

Ну или BS_OWNERDRAW если уж совсем припекло.
Re[2]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.11.19 19:39
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Если нужно выделить как-то выбор то идеологически правильно использовать BS_DEFPUSHBUTTON тип:


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

CS>Ну или BS_OWNERDRAW если уж совсем припекло.


Тогда кнопка будет выпадать из стиля темы.
Re[8]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.11.19 13:05
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Да просто рамки или подчеркивания системного цвета должно быть достаточно.


Оказалось, что еще и рамку-то нарисовать непросто. В обработке WM_NOTIFY и соответствующем контексте можно рисовать только в пределах самой кнопки — например, занять рамкой часть тени, но это выглядит некрасиво. Если же рисовать вокруг кнопки, то это нужно делать в контексте диалогового окна, а вот когда? WM_PAINT диалогам не посылается. Если снова в обработке WM_NOTIFY, то оно посылается только при перерисовке кнопки или ее части — если аккуратно мазнуть по рамке краем другого окна, не задев области кнопки, то WM_NOTIFY не будет, а рамка испортится.

Обрабатывать WM_ERASEBKGND, заливать фон диалога и тут же рисовать в нужном месте рамку — как-то вообще коряво.

Пока получилось только с фиктивным owner-drawn элементом (Button или Static), причем непременно подложенным под кнопку (определенным раньше нее в списке ресурсов диалога), иначе фон этого псевдоэлемента перекрывает кнопку, независимо от WS_EX_TRANSPARENT.

Блин, что ж у них все так через задницу-то... Не зря меня судьба двадцать пять лет хранила от тонкостей GDI...
Re[2]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 18.11.19 11:55
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В крайнем случае сабклассинг этой кнопки


В случае рамки, как оказалось, и сабклассинг не поможет — WM_PAINT и его производные вызываются только для области самой кнопки.
Re[3]: Как изменить цвет кнопки?
От: Pavel Dvorkin Россия  
Дата: 18.11.19 12:04
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:


ЕМ>В случае рамки, как оказалось, и сабклассинг не поможет — WM_PAINT и его производные вызываются только для области самой кнопки.


WM_NCPAINT
With best regards
Pavel Dvorkin
Re[4]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 18.11.19 12:10
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

ЕМ>>В случае рамки, как оказалось, и сабклассинг не поможет — WM_PAINT и его производные вызываются только для области самой кнопки.


PD>WM_NCPAINT


А толку? Область вокруг стандартной кнопки не принадлежит окну, представляющему эту кнопку. То есть, рисовать нужно или по WM_ERASEBKGND для всего диалога, или подкладывать под кнопку фиктивный элемент чуть большего размера, а для стирания рамки еще и добывать текущий/стандартный фон диалога.
Re[5]: Как изменить цвет кнопки?
От: Pavel Dvorkin Россия  
Дата: 18.11.19 13:17
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>А толку? Область вокруг стандартной кнопки не принадлежит окну, представляющему эту кнопку. То есть, рисовать нужно или по WM_ERASEBKGND для всего диалога, или подкладывать под кнопку фиктивный элемент чуть большего размера, а для стирания рамки еще и добывать текущий/стандартный фон диалога.


Что-то не понял. Ты вроде кнопку хотел перерисовать. При чем тут область вокруг кнопки на диалоге ? Такой задачи не ставилось. А рамка кнопки все же принадлежит ей, а не диалогу.
With best regards
Pavel Dvorkin
Re[6]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 18.11.19 22:09
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Ты вроде кнопку хотел перерисовать.


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

PD>При чем тут область вокруг кнопки на диалоге ?


А где еще рисовать рамку?

PD>А рамка кнопки все же принадлежит ей, а не диалогу.


У стандартных кнопок нет рамок — только их собственные границы.
Re[4]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 18.11.19 22:17
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Если не трогать саму кнопку, то можно динамически создавать статик нужного размера и цвета.


Это самый простой, я именно так и сделал. По WM_DRAWITEM просто рисую рамку через FrameRgn, красным — для выделения, фоновым — для стирания.
Re[5]: Как изменить цвет кнопки?
От: qaz77  
Дата: 19.11.19 08:23
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:
По WM_DRAWITEM просто рисую рамку через FrameRgn, красным — для выделения, фоновым — для стирания.

При использовании визуальных тем нет единого фонового цвета.
Диалог или property page может использовать (и в реальности использует) текстуру/градиент.
Чтобы правильно эмулировать отсутствие рамки надо вызывать DrawThemeParentBackground.
Re[6]: Как изменить цвет кнопки?
От: qaz77  
Дата: 19.11.19 08:34
Оценка:
Или еще проще.
Когда рамка не нужна — удаляем статик (или просто не создаем).
Статик всегда рисует одним цветом (красным, например).

Т.е. функция установки рамки для кнопки:
— берет четырехугольник кнопки
— расширяет его во все стороны
— создает статик и устанавливает z-order "под кнопкой"

Для статика можно еще сделать таймер, чтобы оттенки красного
циклически менялись для большей заметности.

Необходимость подсветки кнопки, насколько я понял, выясняется в рантайм,
а не при рисовании формы в редакторе ресурсов.
Соответственно, в обработчике WM_INITDIALOG при необходимости
зовем функцию создания статика для нужной кнопки.
Отредактировано 19.11.2019 8:36 qaz77 . Предыдущая версия .
Re[6]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.11.19 16:18
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Диалог или property page может использовать (и в реальности использует) текстуру/градиент.

Q>Чтобы правильно эмулировать отсутствие рамки надо вызывать DrawThemeParentBackground.

Фон может определяться более, чем одной кистью? Я в прошлом варианте применил FrameRgn как раз для того, чтобы рисовать кистью, а кисть добывал из WNDCLASS::hbrBackground.

Q>Или еще проще. Когда рамка не нужна — удаляем статик (или просто не создаем).


Или делаем невидимым. Сегодня переделал на этот вариант, чтобы отвязаться от необходимости работы с фоном.

Q>Необходимость подсветки кнопки, насколько я понял, выясняется в рантайм


Более того — она может возникнуть в любой момент, так что условия приходится анализировать в WM_TIMER.
Re[2]: Как изменить цвет кнопки?
От: CEMb  
Дата: 20.11.19 02:41
Оценка:
Здравствуйте, CaptainFlint, Вы писали:

CF>Исходя из этого, есть у меня сильное подозрение, что стандартные контролы, вид которых управляется темой, нельзя просто так взять и поменять. Конечно, остаётся ещё вероятность, что существуют какие-то хитрые вызовы; или что тогда их не было, а теперь появились (всё-таки много времени прошло)…


Всё сложнее. Авторы(Windows), когда делали кнопку, сильно оптимизировали. Т.е. нельзя просто перехватить WM_PAINT у кнопки и рисовать туда. Смена состояний, например, тоже вызывает внутреннюю функцию отрисовки, но делает это мимо WM_PAINT.
Если всё-таки сильно хочется, я могу выложить примерный каркас кода для обработчика кнопки, который работает. Мы сабклассили кнопку в промышленных масштабах Правда, у нас была полностью своя отрисовка, но нет особых проблем с тем, чтобы просто поменять тон, сделать grayscale, потом colorize над HDC, тоже могу дать код. Но, моё мнение: это слишком. Я там ниже плюсанул за рамку, сам тоже так делал, когда надо было выделить кнопку. Там есть один момент, под XP+Luna отрисовка кнопки немного захватывает область вокруг себя, так что рамку надо рисовать хотя бы в 2-3 пикселя.
Re[2]: Как изменить цвет кнопки?
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 20.11.19 07:02
Оценка:
Здравствуйте, okon, Вы писали:

ЕМ>>Все действительно настолько плохо, или я где-то чего не догоняю?

O>Потом народ спрашивает а чем WPF лучше.

Чем голое WinAPI? Скинь ссылку, кто так спрашивает, не верю.
Чаще всего WPF просто не появляется в контексте замены WinAPI, потому что придётся менять сразу всё. А WinAPI подразумевает, что приложение компактное и быстрое.
Re[3]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.11.19 13:16
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>под XP+Luna отрисовка кнопки немного захватывает область вокруг себя, так что рамку надо рисовать хотя бы в 2-3 пикселя.


Я как раз три и сделал.
Re[3]: Как изменить цвет кнопки?
От: VVV Россия  
Дата: 21.11.19 19:26
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>DEFPUSHBUTTON предназначен для выделения кнопки по умолчанию. А мне нужно просто подчеркнуть, что есть основания нажать эту кнопку (по которой откроется одно из окон системных настроек), чтобы восстановить работоспособность программы, нарушенную виндовой политикой.


CS>>Ну или BS_OWNERDRAW если уж совсем припекло.


ЕМ>Тогда кнопка будет выпадать из стиля темы.


1. Показать баллон у этой кнопки при необходимости с поясняющим текстом.
2. Рядом с кнопкой поставить статик с картинкой (стрелка, восклицательный знак, радиация, SOS, ...) и при необходимости показывать.
Re[4]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 21.11.19 22:16
Оценка:
Здравствуйте, VVV, Вы писали:

VVV>1. Показать баллон у этой кнопки при необходимости с поясняющим текстом.


У нее есть ToolTip, а при показе рамки он меняется на пояснение, отчего и для чего стоит нажать кнопку. Думаю, этого должно быть достаточно.
Re[5]: Как изменить цвет кнопки?
От: CEMb  
Дата: 22.11.19 07:58
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>У нее есть ToolTip, а при показе рамки он меняется на пояснение, отчего и для чего стоит нажать кнопку. Думаю, этого должно быть достаточно.


Можно ещё завести таймер и "трясти" кнопку ±3 пикселя вверх-вниз, вправо-влево
Re[6]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 22.11.19 10:08
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Можно ещё завести таймер и "трясти" кнопку ±3 пикселя вверх-вниз, вправо-влево


Подозреваю, что это скорее насторожит и создаст опасение перед нажатием кнопки, нежели побудит ее нажать.
Re[7]: Как изменить цвет кнопки?
От: Carc Россия https://vk.com/gosha_mazov
Дата: 22.11.19 16:37
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, CEMb, Вы писали:


CEM>>Можно ещё завести таймер и "трясти" кнопку ±3 пикселя вверх-вниз, вправо-влево


ЕМ>Подозреваю, что это скорее насторожит и создаст опасение перед нажатием кнопки, нежели побудит ее нажать.

Как вариант есть еще два фокуса привлечь внимание
Вариант первый: Блинковать пару-тройку раз. Скрыть — показать. С каким нить таймаутом в 400 мс примерно.

Вариант второй: Тоже блинковать элементом, если он с текстом. Менять ему шрифт: стандартный (который был изначально), этот же но полужирный (FW_BOLD).

Помогает привлечь внимание пользователя.


Как-то так примерно
//функция потока блинкования элемента UI 
DWORD __stdcall BlinkProc_ByVisible(LPVOID lp)
{
    //const std::auto_ptr<BLINK_BY_VIS_PARAM> pParam((BLINK_BY_VIS_PARAM*)lp);

    //const HWND hwnd=(HWND)lp;
    //const HWND hwnd =pParam->hwnd;
        const HWND hwnd=(HWND)lp;
    ASSERT(IsWindow(hwnd));
    if (!IsWindow(hwnd))
        return 1;

    //if (pParam->nSleepBefore)
    //    Sleep(pParam->nSleepBefore);

    //if (!IsWindow(hwnd))
    //    return 1;
    
    enum {TMT_AFTERHIDE=100, TMT_AFTERSHOW=400};

    for(int i=0; i < 3; i++) {
        ::ShowWindow(hwnd,SW_HIDE);
        Sleep(TMT_AFTERHIDE);

        ShowWindow(hwnd,SW_SHOW);
        Sleep(TMT_AFTERSHOW);

        if (!IsWindow(hwnd))
            return 1;
    } 

    return 0;
}

//ну и запуск как-то так
void DoBlinkCtrl(const HWND hwnd)
{
DWORD tid;
const HANDLE hThread=CreateThread(NULL,0,BlinkProc_ByVisible,(LPVOID)hwnd,0,&id);
ASSERT(hThread);
if (hThread)
    CloseHandle(hThread);

}



PS: половина закоментирована, ибо код из реального проекта, там много чего добавляется по сути. Таймауты задержки, возможность дергать через сообщения внешний код перед блинковкой, способы отрисовки и после и.т.д.

Ну это детали и нюансы, суть та же.
Aml Pages Home
Отредактировано 22.11.2019 16:42 Carc . Предыдущая версия . Еще …
Отредактировано 22.11.2019 16:42 Carc . Предыдущая версия .
Re[8]: Как изменить цвет кнопки?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 22.11.19 17:16
Оценка:
Здравствуйте, Carc, Вы писали:

C> enum {TMT_AFTERHIDE=100, TMT_AFTERSHOW=400};


Хм, а какой смысл пару обычных констант с явными значениями определять через enum?
Re[9]: Как изменить цвет кнопки?
От: Carc Россия https://vk.com/gosha_mazov
Дата: 23.11.19 09:23
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Carc, Вы писали:


C>> enum {TMT_AFTERHIDE=100, TMT_AFTERSHOW=400};


ЕМ>Хм, а какой смысл пару обычных констант с явными значениями определять через enum?

Code Style. Стив Макконнел.

Следует избегать непонятных значений. В случае enum мы получаем те же же самые именнованные константы, которые явно своим именем говорят, за что они отвечают.
  • Код яснее и понятнее.
  • Константы определены в одном месте, а не размазаны где-то по коду ниже. Такой код легко сопровождать\модифицировать. Не нужно копаться в кишках кода ниже, где суть вся. (SendMessage, Sleep). В моем случае ведь "кишки" и могут меняться: PostMessage вместо Send***, WaitForObject***, вместо Sleep и.т.д Но это детали. Они где-то там внизу кода. Суть вверху — все сразу ясно и понятно.
  • И потом: вот enum это RVALUE. Причем жесткий такой RVALUE. Здесь не получатся танцы с бубном, вроде const_cast, или взять адрес.

    Простой пример: допустим такой таймаут должен передеваться как in параметр еще в какую функцию. Ок! Все передается, все зер-гут. Даже если мы забыли объявить нашу константу как const UINT наш_таймаут...

    Дальше сосед по цеху, слегка по пьяни, меняет объявление своей функции. Теперь это не in, а in\out параметр.
    И функция получает уже не константную ссылку на const UINT&, а просто ссылку UINT&.

    Ну приспичило ему, рефакторинг-развитие-кода-in\out_параметр-все-дела — нужное подчеркнуть…
    И упс, ранее наш работающий код летит в тартарары…

    В случаем с enum такого не случится. Не скомилится и всё тут. Фига с два вы передадите enum как ссылку, или возьмете адрес ея. Ошибка компиляции. Шо гут, ибо код попросту не даст себя использовать неправильно.

    PS: а вообще юзанье анонимного enum — великое дело для читабельности кода.
    Яркий пример, который люблю юзать налево и направо в многопоточном коде, это ожидание на парочке-троечке-четверочке-[…,далее_везде] хендлов.
    
    
    HANDLE hForWait[2];
    hForWait[0]=hAppClosed;//некий внешний HANDLE, который сигналит фоновым потокам на предмет "хорош ждать", нечто вроде "пользователь закрывает приложение"
    hForWait[1]=hПоСути_там_чего_то_где-то_ну_вроде_данные_с_сервера_пришли;
    
    const DWORD dwWT=WaitForMultipleObjects(ARRAYSIZE(hForWait), hForWait,…);
    
    //и вот тут вот уже нужно помнить, какой хендл сигналит\помер, какой хендл первый в массиве, какой второй - не дай бог ошибиться.
    switch(dwWT) {
    case dwWT-WAIT_FOR_OBJECT_0:
    …
    case dwWT-WAIT_ABANDONED_0 :
    }

    А можно переписать на enum именование.
    Нужно всего лишь все аккуратно проинициализировать в начале, дальше код сам себя поддерживает
    
    //в вот наш enum   для индексов массива хендлов, с говорящими названиями - какой хендл за что отвечает.
    enum {H_APP_CLOSED=0, H_EVENT=1}
    HANDLE hForWait[2];
    hForWait[H_APP_CLOSED]=hAppClosed;//некий внешний HANDLE, который сигналит фоновым потокам на предмет "хорош ждать", нечто вроде "пользователь закрывает приложение"
    hForWait[H_EVENT]=hПоСути_там_чего_то_где-то_ну_вроде_данные_с_сервера_пришли;
    
    const DWORD dwWT=WaitForMultipleObjects(ARRAYSIZE(hForWait), hForWait,…);
    
    //ВУАЛЯ
    //все явно - и все видно!!! какой хендл просигналил
    switch(dwWT - WAIT_FOR_OBJECT_0) {
    case H_APP_CLOSED:
    …
    case H_EVENT:
    }
  • Aml Pages Home
    Отредактировано 23.11.2019 14:44 Carc . Предыдущая версия . Еще …
    Отредактировано 23.11.2019 14:43 Carc . Предыдущая версия .
    Отредактировано 23.11.2019 9:33 Carc . Предыдущая версия .
    Отредактировано 23.11.2019 9:28 Carc . Предыдущая версия .
    Re[10]: Как изменить цвет кнопки?
    От: Евгений Музыченко Франция https://software.muzychenko.net/ru
    Дата: 24.11.19 13:38
    Оценка:
    Здравствуйте, Carc, Вы писали:

    C>Следует избегать непонятных значений. В случае enum мы получаем те же же самые именнованные константы, которые явно своим именем говорят, за что они отвечают.


    Так что мешает определить эти константы, как UINT const Name = Value? Для вящей каноничности можно добавить static.

    C>Код яснее и понятнее.


    С enum — ни разу. enum, по сути своей, предполагает именно перечислимые константы, отличающиеся друг от друга, конкретные значения которых обычно не важны. Конкретные значения обычно задаются для первой константы из какой-либо обособленной группы. enum, в котором все константы имеют конкретные значения, выглядит крайне странно.

    C>И потом: вот enum это RVALUE. Причем жесткий такой RVALUE. Здесь не получатся танцы с бубном, вроде const_cast, или взять адрес.


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

    C>Дальше сосед по цеху, слегка по пьяни, меняет объявление своей функции. Теперь это не in, а in\out параметр.

    C>И функция получает уже не константную ссылку на const UINT&, а просто ссылку UINT&.

    Если передаваемое в функцию значение определено, как константа — компилятор поймает ошибку. А если там еще и при вызове делается принудительное приведение, то налицо не случайная ошибка, а целенаправленная ломка соглашений. При таком подходе проблем избежать невозможно. Если в команде завелся один такой рукожоп — он непременно что-нибудь испортит, и подобные меры не помогут, а вот код в любом случае будет выглядеть странно.

    C>PS: а вообще юзанье анонимного enum — великое дело для читабельности кода.


    Если я вижу enum, то, согласно его смыслу, предполагаю, что там будут определяться в первую очередь константы с различными значениями. То же самое будет предполагать и компилятор. Например, если две константы будут иметь одинаковые значения — он выдаст предупреждение. Другое предупреждение он выдаст, если в switch по enum-переменной обрабатываются не все определенные константы. В Вашем случае эти предупреждения придется подавить. Как предлагаете тогда бороться с кривыми руками "соседей по цеху"? По сути, Вы облегчаете отлов редких ошибок, открывая дорогу более частым.

    C>//в вот наш enum для индексов массива хендлов, с говорящими названиями — какой хендл за что отвечает.

    C>enum {H_APP_CLOSED=0, H_EVENT=1}

    А здесь-то зачем явные значения? Как раз в этом примере enum следовало бы использовать в его родном виде.
    Re[8]: Как изменить цвет кнопки?
    От: CEMb  
    Дата: 25.11.19 10:53
    Оценка:
    Здравствуйте, Carc, Вы писали:

    C>Как вариант есть еще два фокуса привлечь внимание


    О, я вспомнил, как быстро и легко(ну, вроде) подкрасить кнопку:
    1. Снять с кнопки битмап, через HDC/CreateCompatibleDC/BitBlt
    2. Покрасить побайтово с нужным цветом, нужным алгоритмом (алгоритм могу предоставить).
    3. Установит кнопке стиль, что она теперь кнопка с картинкой. Навешать получившуюся картинку.
    4. После возвращения в нормальное состояние, не забыть почистить битмапу

    Тут есть большой минус в том, что кнопка "перестанет" реагировать на мышку, внешне. Но можно исключить из картинки-иконки 2-3 пикселя от бордера, тогда всё будет ок. Будет как та же кнопка, только с красной, например, серединой.
    Re[9]: Как изменить цвет кнопки?
    От: Carc Россия https://vk.com/gosha_mazov
    Дата: 25.11.19 11:07
    Оценка:
    Здравствуйте, CEMb, Вы писали:

    CEM>Здравствуйте, Carc, Вы писали:


    C>>Как вариант есть еще два фокуса привлечь внимание


    CEM>О, я вспомнил, как быстро и легко(ну, вроде) подкрасить кнопку:

    CEM>1. Снять с кнопки битмап, через HDC/CreateCompatibleDC/BitBlt
    CEM>2. Покрасить побайтово с нужным цветом, нужным алгоритмом (алгоритм могу предоставить).
    CEM>3. Установит кнопке стиль, что она теперь кнопка с картинкой. Навешать получившуюся картинку.
    CEM>4. После возвращения в нормальное состояние, не забыть почистить битмапу

    CEM>Тут есть большой минус в том, что кнопка "перестанет" реагировать на мышку, внешне. Но можно исключить из картинки-иконки 2-3 пикселя от бордера, тогда всё будет ок. Будет как та же кнопка, только с красной, например, серединой.


    Не слишком ли для задачи "просто привлечь внимание"!?!


    Да еще с косяками нюансами в сторону! Хренакс, с кнопыч перестал и вовсе реагировать на мыша?
    а) Нюанс са-а-а-а-авсем не очевидный.

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

    в) Ну и к тому же еще "битмапить по черному", а это значит вперед — в режим ядра…

    г) Ну и вообще… Как там насчет Бритвы нашего Оккамы? Не стоит множить сущности без надобности…

    Я б поостерегся… Уж больно нарваться можно с таким кодом. Ни одна, и не две недели с отладчиком наперевес обеспечены.

    С той же видимостью\невидимостью контрола\дочернего окна, хоть теоретически можно подстраховаться в стиле LockResource. Какой-нить банальный класс\struct с обязательным параметром HWND в конструкторе, который соответственно в деструкторе восстанавливает видимость окна.
    В случае сбоя это все равно не спасет. Но хоть что-то…. В случае досрочного завершения функции "блинкования", не нужно хотя бы постоянно помнить, что нужно восстановить видимость контрола.
    Aml Pages Home
    Re[11]: Как изменить цвет кнопки?
    От: Carc Россия https://vk.com/gosha_mazov
    Дата: 25.11.19 11:18
    Оценка:
    Здравствуйте, Евгений Музыченко, Вы писали:

    ЕМ>Здравствуйте, Carc, Вы писали:


    C>>Следует избегать непонятных значений. В случае enum мы получаем те же же самые именнованные константы, которые явно своим именем говорят, за что они отвечают.


    ЕМ>Так что мешает определить эти константы, как UINT const Name = Value?


    Ничто не мешает и забыть указать этот самый const при объявлении.

    С точки зрения компилятора здесь более чем всё идеально. Он и не пикнет даже, если забыли указать const. И потом Ваше забытая_const, уйдет по ссылке в код, который ее таки поменяет. И опять же компилятор не пикнет. Все идеально и корректно.

    В случае enum неправильное использование невозможно. Компилятор сразу даст по рукам за такое.

    ЕМ>Для вящей каноничности можно добавить static.

    На кой фиг здесь static? Эти enum`ы — в моем варианте, или те же const — в Вашем. Определены внутри функции. И никак и никогда не смогут торчать наружу…

    Я это вёл всё к тому, что ошибки делает в 999 из 1000 — человек, программист. Люди ошибаются — ничего не попишешь. В случае с enum — не даст компилятор ошибиться, и всё тут. Либо редизайнить код, и понимать что делаем и зачем. Либо использовать код только так, как задумано. Не выйдет использовать его криво, неправильно просто по невнимательности, спешки, рефакторинга или еще каким причинам.
    Либо код работает правильно, либо не собирается.
    Aml Pages Home
    Re[13]: Как изменить цвет кнопки?
    От: Carc Россия https://vk.com/gosha_mazov
    Дата: 26.11.19 12:03
    Оценка:
    Здравствуйте, Евгений Музыченко, Вы писали:

    ЕМ>Здравствуйте, Carc, Вы писали:


    C>>Забыли указать const для нашего UINT.

    C>>А потом порефакторили, изменили какой-абстрактный код вовне, который изменит эту переменную с забытой const.

    ЕМ>Сдается мне, что Вы преувеличиваете степень риска. Особенностей синтаксиса/семантики, при которых проблема возникает только при "встречных" ошибках в двух и более местах, найдется немало. Если уж заранее применять меры против гипотетических ситуаций, порожденных подобными "встречными" ошибками, то нужно делать анализ синтаксиса, перечислять все возможные сочетания, и блокировать каждое.


    Вообще то "const UINT=…" это изначально и есть "заранее применять меры против"… Только Ваш вариант это полумеры. enum эти задачи решает полностью…

    И синтаксический анализ здесь не поможет. Ибо изначально с точки зрения синтаксиса, что с const, что без — все как раз корректно.
    Aml Pages Home
    Отредактировано 26.11.2019 12:05 Carc . Предыдущая версия .
    Re[14]: Как изменить цвет кнопки?
    От: Евгений Музыченко Франция https://software.muzychenko.net/ru
    Дата: 26.11.19 12:31
    Оценка:
    Здравствуйте, Carc, Вы писали:

    C>Вообще то "const UINT=…" это изначально и есть "заранее применять меры против"…


    Добавление const лишь сообщает компилятору дополнительное свойство объекта, с какими-либо превентивными мерами оно прямо не связано.

    Я не спорю с тем, что enum решает некоторые проблемы с возможными ошибками — говорю лишь о том, что непривычному глазу такие определение странно. Тогда уж лучше традиционные макросы, они понятнее, привычнее, и делают то же самое.
    Re[15]: Как изменить цвет кнопки?
    От: Carc Россия https://vk.com/gosha_mazov
    Дата: 26.11.19 12:50
    Оценка:
    Здравствуйте, Евгений Музыченко, Вы писали:

    ЕМ>Здравствуйте, Carc, Вы писали:


    C>>Вообще то "const UINT=…" это изначально и есть "заранее применять меры против"…


    ЕМ>Добавление const лишь сообщает компилятору дополнительное свойство объекта, с какими-либо превентивными мерами оно прямо не связано.

    Связано. Const объект нельзя изменить, или вызвать неконстантный его метод. По крайней мере без специальных приседаний.

    ЕМ>Я не спорю с тем, что enum решает некоторые проблемы с возможными ошибками — говорю лишь о том, что непривычному глазу такие определение странно. Тогда уж лучше традиционные макросы, они понятнее, привычнее, и делают то же самое.

    Какие еще макросы?
    Это #define MY_VALUE наше_значение что ли?
    Aml Pages Home
    Re[16]: Как изменить цвет кнопки?
    От: Евгений Музыченко Франция https://software.muzychenko.net/ru
    Дата: 26.11.19 13:21
    Оценка:
    Здравствуйте, Carc, Вы писали:

    C>Связано. Const объект нельзя изменить, или вызвать неконстантный его метод.


    Это следствие. Основное назначение — сообщить компилятору свойство объекта (неизменяемость).

    C>Какие еще макросы?

    C>Это #define MY_VALUE наше_значение что ли?

    Ага.
    Re[17]: Как изменить цвет кнопки?
    От: Carc Россия https://vk.com/gosha_mazov
    Дата: 26.11.19 13:50
    Оценка:
    Здравствуйте, Евгений Музыченко, Вы писали:

    ЕМ>Здравствуйте, Carc, Вы писали:


    C>>Связано. Const объект нельзя изменить, или вызвать неконстантный его метод.


    ЕМ>Это следствие. Основное назначение — сообщить компилятору свойство объекта (неизменяемость).

    Та нет… Как раз таки неизменяемость объекта (логическая) это и есть назначение. А свойство: это как раз сообщить компилятору… Вот что компилятор с этим сообщением будет делать(или не делать) — это другой уже вопрос.

    C>>Какие еще макросы?

    C>>Это #define MY_VALUE наше_значение что ли?

    ЕМ>Ага.

    Ну да… Отличная просто идея. Вместо локальной области видимости, в данном случае функции распространить этот #define на всю единицу трансляции. Просто супер!

    Никогда в библиотечном коде не видели чего-нибудь подобного?
    #ifndef КАКАЯ_НИТЬ_WINDOWS_SDK_DEFINE_CONSTANT
    enum {КАКАЯ_НИТЬ_WINDOWS_SDK_DEFINE_CONSTANT = конкретное_значение_скопипастенное_ручками_из_того_же_SDK};
    #endif//#ifndef КАКАЯ_НИТЬ_WINDOWS_SDK_DEFINE_CONSTANT


    Не осенял вопрос: почему именно анонимный enum, а не очередной #define?
    Aml Pages Home
    Re[18]: Как изменить цвет кнопки?
    От: Евгений Музыченко Франция https://software.muzychenko.net/ru
    Дата: 26.11.19 14:19
    Оценка:
    Здравствуйте, Carc, Вы писали:

    C>Никогда в библиотечном коде не видели чего-нибудь подобного?


    Такого (через enum) — никогда. UINT const — видел.
    Re[19]: Как изменить цвет кнопки?
    От: Carc Россия https://vk.com/gosha_mazov
    Дата: 26.11.19 14:26
    Оценка:
    Здравствуйте, Евгений Музыченко, Вы писали:

    ЕМ>Здравствуйте, Carc, Вы писали:


    C>>Никогда в библиотечном коде не видели чего-нибудь подобного?


    ЕМ>Такого (через enum) — никогда. UINT const — видел.

    Это детали: enum или const UINT. Ни никаких #define
    Aml Pages Home
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.