Как менять цвета элементов диалогового окна на Ассемблере

По умолчанию цвета диалоговых окон и элементов управления в приложениях соответствуют установленной палитре Windows. Но иногда бывает необходимо выделить другим цветом какой-нибудь текст в диалоговом окне, или же вообще раскрасить все окно в нужный вам цвет. Это сделать очень легко, надо лишь знать порядок вывода на экран диалоговых окон и их содержимого. При отрисовке каждого элемента диалогового окна ему обязательно передается одно из следующих сообщений: WM_CTLCOLORDLG - отрисовка самого окна, WM_CTLCOLORBTN - отрисовка кнопок, WM_CTLCOLOREDIT - отрисовка полей редактирования, WM_CTLCOLORSTATIC - отрисовка статических элементов, WM_CTLCOLORLISTBOX - отрисовка комбобоксов и выпадающих списков, WM_CTLCOLORMSGBOX - вывод окна сообщений и WM_CTLCOLORSCROLLBAR - отрисовка полосы прокрутки. Обработчик для всех этих сообщений может быть один. Главное, чтобы на этапе инициализации окна был создан объект "кисть" с фоновым цветом главного окна. Именно это значение должен всегда возвращать обработчик сообщение изменения цвета. Предварительный каркас такого приложения выглядит примерно так:
; Обработчик диалогового окна
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

В этом примере все обработчики заданы по максимуму, в вашем приложении можно оставить только необходимое, например, только обработку статических элементов. При написании обработчиков учтите следующие особенности: для read-only или отключенных элементов EDIT сообщение WM_CTLCOLOREDIT не посылается, вместо него посылается сообщение WM_CTLCOLORSTATIC. Цвет текста для кнопок BS_AUTOCHECKBOX и BS_AUTORADIOBUTTON применяется только к их тексту, а флажок кнопок закрашен системно-определенным цветом (обычно черным). Цвет текста для BS_GROUPBOX применяется только к тексту заголовка, но не к линии границы элемента. Также обратите внимание, что цвет задается значениями RGB в трех младших байтах DWORD, при этом оставшийся байт игнорируется.

Теперь рассмотрим сам обработчик установки цвета. В простейшем варианте он выглядит примерно так:
        ; Обработка сообщения установки цвета
color:
        ; Цвета текста и фона элементов
        clrFore = 000000FFh
        clrBack = 0012FFFFh
 
        ; Установить цвет текста
        invoke  SetTextColor,[wparam],clrFore
        ; Установить цвет фона
        invoke  SetBkColor,[wparam],clrBack
        ; Установить режим смешивания фоновых цветов
        invoke  SetBkMode,[wparam],OPAQUE
 
        ; Вернуть объект фоновой кисти окна
        mov     eax,[hBrushBack]
        jmp     processed

При поступлении сообщения на изменение цвета, надо просто установить нужный цвет фона и текста элементу, контекст которого передан в значении wparam сообщения. После этого обработчик обязательно должен вернуть объект фоновой кисти для всего окна, созданной на этапе инициализации окна. При таком обработчике будет просто создано окно нужного цвета, а всем его элементам также будут раскрашены нужным цветом. Но эти цвета будут одинаковы для окна и всех его элементов.

Теперь усовершенствуем обработчик установки цвета, чтобы мы могли изменять цвета только нужных нам элементов и только в тот момент, когда нам это надо. Для этого воспользуемся удобнейшими функциями SetProp и GetProp. Вкратце, они позволяют присваивать любому окну или элементу окна произвольное свойство, которое остается закрепленным за ним, пока окно не будет закрыто. В нашем случае где-то в приложении мы будем устанавливать отдельным элементам диалогового окна нужный нам цвет фона и цвет текста, а в обработчике установки цвета будем устанавливать эти значения. Если у элемента не установлены значения цвета, то такой элемент обрабатываться не будет.
; Определение констант свойств
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

Обновление элемента выполняется примерно так. Этот код можно вызывать в любой момент времени после создания окна:
        ; Обновить окно 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

Если требуется поменять только цвет текста, то значение цвета фона предварительно получите при помощи функции GetSysColor с параметром COLOR_WINDOW. Аналогично, если требуется поменять только цвет фона. Как видите, ничего сложного в управлении цветом нет. Но здесь, как и в любом другом деле, главное не переборщить.

В приложении две программы с исходными текстами. Первая просто отрисовывает диалоговое окно с элементами заданного цвета, вторая позволяет менять цвета текста и фона отдельных элементов по нажатию на кнопку.
Добавлено: 13 Сентября 2013 04:20:12 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...