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

Картинка для окна
Картинку надо сохранить в формате BMP, с глубиной цвета 8 бит. Это очень важно, так как в этом случае количество цветов в палитре не превышает 256, а каждая точка описывается ровно одним байтом. Поскольку картинка будет накладываться на диалоговое окно, то и хранить ее надо будет в ресурсах. Тут есть важная особенность: в ресурсах картинка хранится без 14-байтного заголовка BITMAPFILEHEADER и все смещения считаются сразу же от начала блока BITMAPINFOHEADER.
Нам потребуется вспомогательная функция для получения цвета точки. В ней учтены особенности формата BMP, а именно то, что пиксели хранятся построчно, снизу вверх, а каждая строка изображения дополняется нулями до длины, кратной четырем байтам.
Code (Assembler) : Убрать нумерацию
- ;----------------------------------------------------------
- ; Процедура получения цвета точки с координатами X,Y
- ;----------------------------------------------------------
- ; dXCoord - X-координата запрашиваемой точки
- ; dYCoord - Y-координата запрашиваемой точки
- ; bmpX - ширина картинки
- ; bmpY - высота картинки
- ; bitmapData - указатель на начало массива картинки
- ; palData - указатель на начало массива палитры
- ; На выходе: EAX - RGB цвет точки из палитры
- ;----------------------------------------------------------
- proc GetPixelColorAt dXCoord:dword, dYCoord:dword, bmpX:dword,\
- bmpY:dword, bitmapData:dword, palData:dword
- ; Сохранить изменяемые регистры
- push esi ecx edx
- ; Проверка валидноости координат
- xor eax,eax
- mov esi,[dXCoord]
- cmp esi,[bmpX]
- ja @f
- mov esi,[dYCoord]
- cmp esi,[bmpY]
- ja @f
- ; Вычислить указатель на точку в картинке
- mov eax,