Blog. Just Blog

Как изменить цвет кнопок диалогового окна

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Когда-то давно в одной из статей я рассказывал, как менять цвета различных элементов диалоговых окон Windows. Наверняка вы обратили внимание, что элемент типа BUTTON, то есть кнопка, выбивается из общей схемы и на изменение цвета не реагирует должным образом. Решить эту проблему все-таки можно, но для этого придется самостоятельно отрисовывать все компоненты кнопки - фон, рамку и надпись. Зато такой способ открывает неограниченные возможности по кастомизации кнопок.

Первым делом в ресурсах или в функции создания кнопки через CreateWindow(Ex) надо дополнить стиль модифицируемой кнопки параметром BS_OWNERDRAW. С этого момента все функции по рисованию перекладываются на наше приложение. Для этого приложение должно обрабатывать сообщение WM_DRAWITEM. Окну-владельцу кнопки в параметре lParam этого сообщения передается указатель на структуру DRAWITEMSTRUCT, на основании которой мы и будем заниматься рисованием.
  1.         cmp     [msg],WM_DRAWITEM
  2.         je      color_button
  3.         ...
  4.         ...
  5. color_button:
  6.         ; Указатель на структуру DRAWITEMSTRUCT
  7.         mov     ebx,[lparam]
  8.  
  9.         ; Установить режим смешивания фоновых цветов
  10.         invoke  SetBkMode,[ebx+DRAWITEMSTRUCT.hDC],TRANSPARENT
  11.  
  12.         ; Кнопка активна?
  13.         test    [ebx+DRAWITEMSTRUCT.itemState],ODS_SELECTED
  14.         jz      @f
  15.  
  16.         invoke  GetSysColor,COLOR_ACTIVEBORDER
  17.         invoke  CreatePen,PS_SOLID,1,eax
  18.         invoke  SelectObject,[ebx+DRAWITEMSTRUCT.hDC],eax
  19.  
  20.         invoke  GetSysColor,COLOR_3DLIGHT
  21.         invoke  CreateSolidBrush,eax
  22.         invoke  SelectObject,[ebx+DRAWITEMSTRUCT.hDC],eax
  23.  
  24.         ; Прямоугольник с заливкой
  25.         invoke  Rectangle,[ebx+DRAWITEMSTRUCT.hDC],\
  26.                 [ebx+DRAWITEMSTRUCT.rcItem.left],\
  27.                 [ebx+DRAWITEMSTRUCT.rcItem.top],\
  28.                 [ebx+DRAWITEMSTRUCT.rcItem.right],\
  29.                 [ebx+DRAWITEMSTRUCT.rcItem.bottom]
  30.  
  31.         jmp     loc_text
  32. @@:
  33.         ; Установить цвет и стиль рамки
  34.         invoke  GetSysColor,COLOR_3DDKSHADOW
  35.         invoke  CreatePen,PS_SOLID,3,eax
  36.         invoke  SelectObject,[ebx+DRAWITEMSTRUCT.hDC],eax
  37.  
  38.         ; Установить цвет фона
  39.         invoke  GetSysColor,COLOR_HIGHLIGHT
  40.         invoke  CreateSolidBrush,eax
  41.         invoke  SelectObject,[ebx+DRAWITEMSTRUCT.hDC],eax
  42.  
  43.         ; Прямоугольник с заливкой
  44.         invoke  Rectangle,[ebx+DRAWITEMSTRUCT.hDC],\
  45.                 [ebx+DRAWITEMSTRUCT.rcItem.left],\
  46.                 [ebx+DRAWITEMSTRUCT.rcItem.top],\
  47.                 [ebx+DRAWITEMSTRUCT.rcItem.right],\
  48.                 [ebx+DRAWITEMSTRUCT.rcItem.bottom]
  49.  
  50. loc_text:
  51.         ; Длина надписи на кнопке
  52.         invoke  GetWindowTextLength,[ebx+DRAWITEMSTRUCT.hwndItem]
  53.         inc     eax
  54.         mov     [len],eax
  55.         invoke  GetWindowText,[ebx+DRAWITEMSTRUCT.hwndItem],buff,[len]
  56.  
  57.         ; Установить цвет текста
  58.         invoke  SetTextColor,[ebx+DRAWITEMSTRUCT.hDC],0x0000FFFF
  59.  
  60.         ; Для нажатой кнопки сдвинуть текст вниз-вправо
  61.         test    [ebx+DRAWITEMSTRUCT.itemState],ODS_SELECTED
  62.         jz      @f
  63.  
  64.         ; Установить цвет текста
  65.         invoke  SetTextColor,[ebx+DRAWITEMSTRUCT.hDC],0x000000FF
  66.  
  67.         add     [ebx+DRAWITEMSTRUCT.rcItem.left],2
  68.         add     [ebx+DRAWITEMSTRUCT.rcItem.top],2
  69. @@:
  70.         ; Надпись на кнопке
  71.         lea     esi,[ebx+DRAWITEMSTRUCT.rcItem]
  72.         invoke  DrawText,[ebx+DRAWITEMSTRUCT.hDC],buff,[len],esi,\
  73.                 DT_SINGLELINE+DT_VCENTER+DT_CENTER
В зависимости от состояния кнопки, нажата она или нет, меняется цвет фона, цвет текста и стиль рамки. Здесь рамка нарисована единым цветом и толщиной, но при необходимости можно заморочиться и нарисовать "трехмерные" границы с помощью функций MoveToEx и LineTo. Еще было бы правильным проверять, что цвета меняются именно для нужной кнопки, делается это проверкой элемента itemID в структуре DRAWITEMSTRUCT. В приведенном примере я это осознанно пропустил, чтобы не загромождать код.

В приложении пример программы с исходным текстом, демонстрирующей создание и обработку кастомизированной кнопки в диалоговом окне.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Color.Button.Demo.zip (2,996 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 1984 | Комментариев: 0

Метки: Assembler
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 2 (0.0066 сек.) / Память: 4.5 Mb
Наверх