Blog. Just Blog

Окна нестандартной формы на Ассемблере. Часть 2

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

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

Картинка для окна
Картинка для окна

Картинку надо сохранить в формате BMP, с глубиной цвета 8 бит. Это очень важно, так как в этом случае количество цветов в палитре не превышает 256, а каждая точка описывается ровно одним байтом. Поскольку картинка будет накладываться на диалоговое окно, то и хранить ее надо будет в ресурсах. Тут есть важная особенность: в ресурсах картинка хранится без 14-байтного заголовка BITMAPFILEHEADER и все смещения считаются сразу же от начала блока BITMAPINFOHEADER.

Нам потребуется вспомогательная функция для получения цвета точки. В ней учтены особенности формата BMP, а именно то, что пиксели хранятся построчно, снизу вверх, а каждая строка изображения дополняется нулями до длины, кратной четырем байтам.
  1. ;----------------------------------------------------------
  2. ; Процедура получения цвета точки с координатами X,Y
  3. ;----------------------------------------------------------
  4. ; dXCoord    - X-координата запрашиваемой точки
  5. ; dYCoord    - Y-координата запрашиваемой точки
  6. ; bmpX       - ширина картинки
  7. ; bmpY       - высота картинки
  8. ; bitmapData - указатель на начало массива картинки
  9. ; palData    - указатель на начало массива палитры
  10. ; На выходе: EAX - RGB цвет точки из палитры
  11. ;----------------------------------------------------------
  12. proc GetPixelColorAt dXCoord:dword, dYCoord:dword, bmpX:dword,\
  13.                      bmpY:dword, bitmapData:dword, palData:dword
  14.  
  15.         ; Сохранить изменяемые регистры
  16.         push    esi ecx edx
  17.  
  18.         ; Проверка валидноости координат
  19.         xor     eax,eax
  20.         mov     esi,[dXCoord]
  21.         cmp     esi,[bmpX]
  22.         ja      @f
  23.         mov     esi,[dYCoord]
  24.         cmp     esi,[bmpY]
  25.         ja      @f
  26.  
  27.         ; Вычислить указатель на точку в картинке
  28.         mov     eax,