
Быстрый поиск
Введите фрагмент названия статьи для поиска

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

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

Окна нестандартной формы на Ассемблере. Часть 1
22.06.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Фигурная резьба по деревянным окнам - старинное народное творчество. А в нашем 21-м веке народным творчеством будет резьба по окнам Windows. При умелом использовании это станет стильным украшением для ваших приложений, добавив им привлекательности.Форма окна определяется особыми структурами, называемыми регионами. Они могут быть прямоугольной формы, закругленной, эллиптической и многоугольной. Весь принцип работы с регионами сводится к следующему. Сперва создается главный регион, равный по размерам основному диалоговому окну, затем создаются дополнительные регионы нужного размера и накладываются на него с нужной битовой маской. Режимы наложения определяют будет ли новый регион удален из основного, или же наоборот добавлен. Размер главного региона лучше всего рассчитывать из результатов функции GetClientRect, вызванной с хэндлом нужного диалогового окна. Наложение регионов выполняется функцией CombineRgn, возможные режимы наложения смотрите в официальной документации. Все действия выполняются на этапе инициализации окна по событию WM_INITDIALOG.
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- hRMain dd ? ; Хэндл главного региона окна
- coord RECT ; Координаты окна для вычисления размера региона
- ...
Читать статью целиком »
Просмотров: 7278 | Комментариев: 1

Всплывающее окно на Ассемблере
26.05.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Всплывающее окно - удобный способ информировать о том, что ваша программа выполнила какое-то действие, не требующее немедленного вмешательства пользователя, но достаточно важное, чтобы он об этом узнал. Это может быть сообщение о завершении закачки файла, получении нового письма, завершении длительных вычислений и т.п. Красивый эффект получается, когда информационное окно плавно выезжает из-под таскбара. Простого перемещения окна тут будет недостаточно, так как придется учитывать положение таскбара и всяких других панелей, которые резервируют под себя часть рабочего стола. Поэтому надо сперва получить размер видимой области экрана с учетом различных панелей инструментов и размеры самого всплывающего окна. Затем окно перемещается по одному пикселу в нужном направлении с учетом положения панелей, а размер его видимой части увеличивается на один пиксел в противоположную сторону. Это делается при помощи функции MoveWindow. Лучше всего сам эффект всплытия реализовать на стадии инициализации окна по сообщению WM_INITDIALOG, но в этом случае придется принудительно показывать окно функцией ShowWindow и обновлять его содержимое функцией UpdateWindow после каждого сдвига. Рекомендуются стили окна без заголовка и поверх всех окон, как сделано в прилагаемом примере. Атрибут прозрачности для всплывающих окон лучше не использовать, так как при анимации появляются заметные искажения.Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- coord RECT ; Размеры окна
- screen RECT ; Размеры экрана
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Обработчик сообщения WM_INITDIALOG
- wminitdialog:
- ; Получить размер рабочей области экрана
- invoke SystemParametersInfo,SPI_GETWORKAREA,NULL,screen,FALSE
- ; Получить размер окна
- invoke GetClientRect,[hwnddlg],coord
- ; Вычислить отступ от правой границы экрана
- mov eax,[screen.right]
- sub eax,[coord.right]
- dec eax
- mov [screen.right],eax
- ; Высота окна
- mov ecx,[coord.bottom]
- ; Цикл всплытия окна
- @@:
- ; Сохранить значение счетчика
- push ecx
- ; Заполняем стек для MoveWindow
- push TRUE
- mov eax,[coord.bottom]
- sub eax,ecx
- push eax
- push [coord.right]
- mov ecx,[screen.bottom]
- sub ecx,eax
- push ecx
- invoke MoveWindow,[hwnddlg],[screen.right]
- ; Так как сейчас только инициализация, то придется принудительно
- ; показать окно и обновить его содержимое
- invoke ShowWindow,[hwnddlg], SW_SHOW
- invoke UpdateWindow,[hwnddlg]
- ; Небольшая пауза
- invoke Sleep,2
- ; Восстановить счетчик
- pop ecx
- loop @b
- ...
Читать статью целиком »
Просмотров: 6157 | Комментариев: 2

Магнитное (липкое) окно на Ассемблере
12.05.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Еще один интересный трюк при работе с окнами - так называемые "липкие" или "магнитные" окна, которые прилипают к границам экрана при перемещении. Это реализуется достаточно просто, но выглядит очень эффектно. Для перехвата перемещения окна надо обрабатывать сообщение WM_MOVING. В параметре lParam передается адрес структуры RECT, которая содержит значения конечных координат окна после отпускания курсора мыши. Чтобы при изменении координат окна не возникало неприятного эффекта моргания, их надо менять сразу же в передаваемой структуре. Обработчик WM_MOVING выглядит следующим образом:Code (Assembler) : Убрать нумерацию
- ; Обработчик сообщения WM_MOVING
- MAX_GRID = 20 ; Размер магнитной сетки
- ; Получить размер рабочей области экрана
- invoke SystemParametersInfo,SPI_GETWORKAREA,NULL,coord,FALSE
- ; В регистре EDI указатель на структуру координат окна
- mov edi,[lparam]
- ; Проверить положение левой границы окна
- mov edx,[edi+RECT.left]
- sub edx,[coord.left]
- mov eax,edx
- jns @f
- neg edx
- @@:
- cmp edx,MAX_GRID
- ja @f
- sub [edi+RECT.right],eax
- sub [edi+RECT.left],eax
- @@:
- ; Проверить положение правой границы окна
- mov edx,[edi+RECT.right]
- sub edx,[coord.right]
- mov eax,edx
- jns @f
- neg edx
- @@:
- cmp edx,MAX_GRID
- ja @f
- sub [edi+RECT.right],eax
- sub [edi+RECT.left],eax
- @@:
- ; Проверить положение верхней границы окна
- mov edx,[edi+RECT.top]
- sub edx,[coord.top]
- mov eax,edx
- jns @f
- neg edx
- @@:
- cmp edx,MAX_GRID
- ja @f
- sub [edi+RECT.top],eax
- sub [edi+RECT.bottom],eax
- @@:
- ; Проверить положение нижней границы окна
- mov edx,[edi+RECT.bottom]
- sub edx,[coord.bottom]
- mov eax,edx
- jns @f
- neg edx
- @@:
- cmp edx,MAX_GRID
- ja @f
- sub [edi+RECT.top],eax
- sub [edi+RECT.bottom],eax
- @@:
- mov eax,TRUE
- jmp finish
Читать статью целиком »
Просмотров: 5436 | Комментариев: 11

Расчет CRC32 на Ассемблере
27.04.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Алгоритм вычисления контрольной суммы (CRC, англ. cyclic redundancy code, циклический избыточный код) - способ цифровой идентификации некоторой последовательности данных, который заключается в вычислении контрольного значения ее циклического избыточного кода. Алгоритм CRC32 основан на примитивном полиноме 0EDB88320h и применяется в архиваторах, системах шифрования, протекторах исполняемых файлов и многих других программах. Он прост в реализации и с большой вероятностью может подтверждать неизменность данных, причем чем меньше размер контролируемой информации, тем выше эта вероятность. Для расчета CRC32 требуется сперва подготовить так называемую таблицу инициализации. В сегменте данных таблица резервируется как 256 двойных слов, по одному dword на каждый возможный байт:Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- ; Таблица инициализации для расчета CRC32
- crc32table rd 256
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция создания таблицы инициализации для расчета CRC32
- ;-----------------------------------------------------------------------
- proc init_CRC32
- push eax ebx ecx edi
- mov edi,crc32table ; Указатель на выделенную под таблицу память
- xor ebx,ebx ; Расчитать значения для всех 256 байт
- calc_crc32table:
- mov eax,ebx
- mov ecx,8
- do_polynom:
- shr eax,1 ; Проверить четность байта
- jnc @f ; XOR выполняется только если байт нечетный
- xor eax,0EDB88320h
- @@:
- loop do_polynom ; Следующий бит
- stosd ; Записать полученный dword в таблицу
- inc ebx
- cmp ebx,256
- jb calc_crc32table ; Следующий байт
- pop edi ecx ebx eax
- ret
- endp
Читать статью целиком »
Просмотров: 13601 | Комментариев: 9
