Как менять цвета элементов диалогового окна на Ассемблере
По умолчанию цвета диалоговых окон и элементов управления в приложениях соответствуют установленной палитре Windows. Но иногда бывает необходимо выделить другим цветом какой-нибудь текст в диалоговом окне, или же вообще раскрасить все окно в нужный вам цвет. Это сделать очень легко, надо лишь знать порядок вывода на экран диалоговых окон и их содержимого. При отрисовке каждого элемента диалогового окна ему обязательно передается одно из следующих сообщений: WM_CTLCOLORDLG - отрисовка самого окна, WM_CTLCOLORBTN - отрисовка кнопок, WM_CTLCOLOREDIT - отрисовка полей редактирования, WM_CTLCOLORSTATIC - отрисовка статических элементов, WM_CTLCOLORLISTBOX - отрисовка комбобоксов и выпадающих списков, WM_CTLCOLORMSGBOX - вывод окна сообщений и WM_CTLCOLORSCROLLBAR - отрисовка полосы прокрутки. Обработчик для всех этих сообщений может быть один. Главное, чтобы на этапе инициализации окна был создан объект "кисть" с фоновым цветом главного окна. Именно это значение должен всегда возвращать обработчик сообщение изменения цвета. Предварительный каркас такого приложения выглядит примерно так:Code (Assembler) : Убрать нумерацию
- ; Обработчик диалогового окна
- proc DialogProc hwnddlg,msg,wparam,lparam
- ...
- ; Обработка сообщения инициализации окна
- cmp [msg],WM_INITDIALOG
- je wminitdialog
- ; Обработка всех сообщений, связанных с установкой цвета
- cmp [msg],WM_CTLCOLORDLG
- je color
- cmp [msg],WM_CTLCOLORBTN
- je color
- cmp [msg],WM_CTLCOLOREDIT
- je color
- cmp [msg],WM_CTLCOLORSTATIC
- je color
- cmp [msg],WM_CTLCOLORLISTBOX
- je color
- cmp [msg],WM_CTLCOLORMSGBOX
- je color
- cmp [msg],WM_CTLCOLORSCROLLBAR
- je color
- ...
- ; Обработка инициализации окна
- wminitdialog:
- ; Основной цвет фона окна в формате RGB
- clrMain = 0012FFFFh
- ; Создать объект фоновой кисти для всего окна
- invoke CreateSolidBrush,clrMain
- mov [hBrushBack], eax
- jmp processed
Теперь рассмотрим сам обработчик установки цвета. В простейшем варианте он выглядит примерно так:
Code (Assembler) : Убрать нумерацию
- ; Обработка сообщения установки цвета
- color:
- ; Цвета текста и фона элементов
- clrFore = 000000FFh
- clrBack = 0012FFFFh
- ; Установить цвет текста
- invoke SetTextColor,[wparam],clrFore
- ; Установить цвет фона
- invoke SetBkColor,[wparam],clrBack
- ; Установить режим смешивания фоновых цветов
- invoke SetBkMode,[wparam],OPAQUE
- ; Вернуть объект фоновой кисти окна
- mov eax,[hBrushBack]
- jmp processed
Теперь усовершенствуем обработчик установки цвета, чтобы мы могли изменять цвета только нужных нам элементов и только в тот момент, когда нам это надо. Для этого воспользуемся удобнейшими функциями SetProp и GetProp. Вкратце, они позволяют присваивать любому окну или элементу окна произвольное свойство, которое остается закрепленным за ним, пока окно не будет закрыто. В нашем случае где-то в приложении мы будем устанавливать отдельным элементам диалогового окна нужный нам цвет фона и цвет текста, а в обработчике установки цвета будем устанавливать эти значения. Если у элемента не установлены значения цвета, то такой элемент обрабатываться не будет.
Code (Assembler) : Убрать нумерацию
- ; Определение констант свойств
- PROP_COLOR = 101
- PROP_BACK = 102
- ; Обработка сообщения установки цвета
- ; В [lparam] - хэндл окна элемента, которому устанавливается цвет
- color:
- ; Получить значение цвета текста
- invoke GetProp,[lparam],PROP_COLOR
- or eax,eax
- jz @f
- ; Установить цвет текста
- invoke SetTextColor,[wparam],eax
- @@:
- ; Получить значение цвета фона
- invoke GetProp,[lparam],PROP_BACK
- or eax,eax
- jz @f
- ; Установить цвет фона
- invoke SetBkColor,[wparam],eax
- @@:
- ; Установить режим смешивания фоновых цветов
- invoke SetBkMode,[wparam],OPAQUE
- ; Вернуть объект фоновой кисти окна
- mov eax,[hBrushBack]
- jmp processed
Code (Assembler) : Убрать нумерацию
- ; Обновить окно STATIC1
- invoke GetDlgItem,[hwnddlg],ID_ST1
- mov ebx,eax
- ; Установить значение цвета текста
- invoke SetProp,ebx,PROP_COLOR,clrFore
- ; Установить значение цвета фона
- invoke SetProp,ebx,PROP_BACK,clrBack
- ; Перерисовать элемент с новым цветом
- invoke InvalidateRect,ebx,NULL,TRUE
В приложении две программы с исходными текстами. Первая просто отрисовывает диалоговое окно с элементами заданного цвета, вторая позволяет менять цвета текста и фона отдельных элементов по нажатию на кнопку.
Просмотров: 13609 | Комментариев: 12
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(01.05.2020 в 08:25):
Ну вот, к штанам добавляется рубашка через ноги. Чем принципиально отличается создание статиков на лету от статиков в ресурсах? Нарисовал в нужный момент сколько надо статиков, потом отправил InvalidateRect их родительскому окну и готово, никаких енумов, никаких GetWindowLong.
https://www.upload.ee/files/11...lor.zip.html
Дальше или сам или за деньги.
https://www.upload.ee/files/11...lor.zip.html
Дальше или сам или за деньги.
Alex
(01.05.2020 в 06:52):
Я внимательно прочитал вашу статью, очень хорошая и главное доступно все описано. Но в вашей статье статики выполнены при помощи ресурсов, а у меня все делается при помощи CreateWindowEx, как Child. Выбираю контрол при помощи EnumChildWindows и обратного вызова GetWindowLong. По этому у меня закрашивается только последний.
ManHunter
(28.04.2020 в 10:37):
Насколько я знаю - нет. Да и смысл? Это как штаны через голову надевать, есть же нормальные рабочие решения. Как работать с отдельным элементом, хоть статиком, хоть едитом, я в статье написал.
Alex
(28.04.2020 в 07:35):
Можно ли поменять цвет отдельного статика из нескольких,
не используя сообщение WM_CTLCOLORSTATIC.
Допустим как то через WM_PAINT
не используя сообщение WM_CTLCOLORSTATIC.
Допустим как то через WM_PAINT
ManHunter
(12.02.2015 в 17:24):
Поменять нельзя. Можно нарисовать свой static с какой угодно иконкой/битмапом и потом эмулировать работу чекбокса, меняя иконку/битмап у статика в зависимости от его текущего состояния. Это хорошо делается через субклассирование.
Евгений
(12.02.2015 в 17:21):
Здравствуйте. Не подскажете, как можно поменять цвет чекбокса? и вообще перерисовать его можно как-то или битмап наложить?
ManHunter
(27.10.2013 в 13:56):
"Buttons with the BS_PUSHBUTTON, BS_DEFPUSHBUTTON, or BS_PUSHLIKE styles do not use the returned brush. Buttons with these styles are always drawn with the default system colors"
MSDN -> BS_OWNERDRAW, WM_DRAWITEM, DrawItem
Придется самому рисовать кнопку, используя стиль BS_OWNERDRAW, затем отлавливать и обрабатывать WM_DRAWITEM. Не самая тривиальная задача, но вполне решаемая.
http://stackoverflow.com/quest...ton-winapi-c
Как вариант - использовать картинки. Вот хороший пример:
http://www.johnfindlay.plus.co...g/ownbut.zip
MSDN -> BS_OWNERDRAW, WM_DRAWITEM, DrawItem
Придется самому рисовать кнопку, используя стиль BS_OWNERDRAW, затем отлавливать и обрабатывать WM_DRAWITEM. Не самая тривиальная задача, но вполне решаемая.
http://stackoverflow.com/quest...ton-winapi-c
Как вариант - использовать картинки. Вот хороший пример:
http://www.johnfindlay.plus.co...g/ownbut.zip
mikado3333
(26.10.2013 в 07:16):
ManHunter, подскажите а как поменять цвет у кнопки созданной функциией "CreateWindowEx"?
brute
(10.01.2013 в 18:37):
нашел всё-таки пример с кнопкой: C:\masm32\examples\exampl07\butntest
но мне в нем не разобраться - слишком сложно наворочено..
но мне в нем не разобраться - слишком сложно наворочено..
ManHunter
(09.01.2013 в 12:41):
brute, ну так скомпилированный файл - это ж и есть практически ассемблер :) Дизассемблируешь твой пример, получаешь ассемблерный код. Компилируешь обратно и получаешь красивую кнопочку на асме.
PROP_COLOR и PROP_BACK - это что-то типа индексов в массиве свойств. Можно задавать просто цифрами, но так кошернее. А описания *Prop лучше смотреть на MSDN, там все очень хорошо расписано.
PROP_COLOR и PROP_BACK - это что-то типа индексов в массиве свойств. Можно задавать просто цифрами, но так кошернее. А описания *Prop лучше смотреть на MSDN, там все очень хорошо расписано.
brute
(09.01.2013 в 12:35):
asm, конечно, крут, но вот такую кнопочку на нём ни в жизнь не заделать:
http://webfile.ru/6306578
в первом примере (да и во втором) не работают цвета кнопок и длгфрейма - сие и неудивительно - подобных примеров в инете (рдсн и папке масм32) не нашёл. Не совсем понятно про функции Prop (опять же из-за отсутствия примеров в других источниках) - они типа флажков? зачем нужны константы PROP_COLOR и PROP_BACK? Насколько нужны эти функции - можно ли менять цвет как в первом примере, обрабатывая on_click?
http://webfile.ru/6306578
в первом примере (да и во втором) не работают цвета кнопок и длгфрейма - сие и неудивительно - подобных примеров в инете (рдсн и папке масм32) не нашёл. Не совсем понятно про функции Prop (опять же из-за отсутствия примеров в других источниках) - они типа флажков? зачем нужны константы PROP_COLOR и PROP_BACK? Насколько нужны эти функции - можно ли менять цвет как в первом примере, обрабатывая on_click?
Добавить комментарий
Заполните форму для добавления комментария
Все нашел, где я тупил.
Просто мозг вскипел.