Образ мышления: Assembler
То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал
Образ мышления: Assembler - Карта сайта
Гиперссылки в диалоговых окнах на Ассемблере
11.07.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Создание текстовой гиперссылки в диалоговом окне, казалось бы, простая задача. Но дело в том, что в Windows по умолчанию нет элементов диалоговых окон, которые бы выполняли роль гиперссылки. Готовых решений на FASM тоже не нашлось, значит придется создавать такой элемент самостоятельно. Сперва определимся с задачами, что нам надо сделать. Должен получиться элемент диалогового окна в виде текста определенного цвета, при наведении на который курсор должен менять свою форму, а цвет изменяться на подсвеченный. При клике на такой элемент должна открываться заданная ссылка. Задачи ясны, начнем их решать. Сперва выберем элемент диалоговых окон из списка стандартных, который и будет использоваться в качестве гиперссылки. Сразу же приходит на ум STATIC. По умолчанию элемент класса STATIC полностью оправдывает свое название и не реагирует практически ни на какие сообщения. Чтобы STATIC принимал движение курсора и нажатия клавиш мышки, его надо описать в ресурсах с флагом стилей SS_NOTIFY.А как отследить движение курсора только над нашей гиперссылкой? Тут нам на помощь придет такая полезная вещь, как субклассирование. Суть субклассирования проста. С каждым окном связан указатель на оконную процедуру, которая обрабатывает сообщения Windows. Когда система получает сообщение, предназначенное для некоторого окна, она находит адрес оконной процедуры этого окна и вызывает ее. При субклассировании мы заменяем эту процедуру нашей и сохраняем указатель на старую процедуру, чтобы можно было передать ей сообщения для дальнейшей обработки. Это делается функцией SetWindowLong с индексом GWL_WNDPROC на этапе инициализации главного окна:
Code (Assembler) : Убрать нумерацию
- ...
- ; Получить хэндл нашего STATIC'а
- invoke GetDlgItem,[hwnddlg],ID_LINK
- ; Субклассировать гиперссылку и установить собственный
- ; обработчик для STATIC'а
- invoke SetWindowLong,eax,GWL_WNDPROC,WindowProc
- ; Сохранить адрес предыдущего обработчика
- mov [OldWndProc],eax
- ...
Читать статью целиком »
Просмотров: 6932 | Комментариев: 6
Окна нестандартной формы на Ассемблере. Часть 2
24.06.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
В первой части статьи я рассказал как создавать окна нестандартной формы при помощи регионов. У этого способа есть один большой недостаток: создаваемые окна так или иначе состоят из четких геометрических форм. Но высший пилотаж - это окна в форме картинок, и сейчас я расскажу как они делаются. Сперва немного теоретических выкладок. В графическом файле формата BMP информация о картинке хранится в растровом виде, то есть каждый пиксел описан определенным цветом. Рекомендую внимательно прочитать документацию о формате BMP-файла, так как есть несколько важных моментов. Создание окна нестандартной формы на основе растровой картинки заключается в наложении изображения на диалоговое окно и удалении всех его регионов, в которых находятся точки определенного цвета. Этот цвет мы будем считать "прозрачным", потому что настоящую прозрачность обычный формат BMP не поддерживает. А удалять отдельные регионы мы уже умеем.Итак, берем нужную картинку и накладываем ее на какой-нибудь однородный цветной фон, причем цвет фона не должен присутствовать на основной картинке. Можно добавить надпись, но главное чтобы границы всех элементов композиции были четкими и не сливались с фоном. Получится примерно следующее:
Картинка для окна
Картинку надо сохранить в формате BMP, с глубиной цвета 8 бит. Это очень важно, так как в этом случае количество цветов в палитре не превышает 256, а каждая точка описывается ровно одним байтом. Поскольку картинка будет накладываться на диалоговое окно, то и хранить ее надо будет в ресурсах. Тут есть важная особенность: в ресурсах картинка хранится без 14-байтного заголовка BITMAPFILEHEADER и все смещения считаются сразу же от начала блока BITMAPINFOHEADER.
Читать статью целиком »
Просмотров: 7671 | Комментариев: 11
Окна нестандартной формы на Ассемблере. Часть 1
22.06.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Фигурная резьба по деревянным окнам - старинное народное творчество. А в нашем 21-м веке народным творчеством будет резьба по окнам Windows. При умелом использовании это станет стильным украшением для ваших приложений, добавив им привлекательности.Форма окна определяется особыми структурами, называемыми регионами. Они могут быть прямоугольной формы, закругленной, эллиптической и многоугольной. Весь принцип работы с регионами сводится к следующему. Сперва создается главный регион, равный по размерам основному диалоговому окну, затем создаются дополнительные регионы нужного размера и накладываются на него с нужной битовой маской. Режимы наложения определяют будет ли новый регион удален из основного, или же наоборот добавлен. Размер главного региона лучше всего рассчитывать из результатов функции GetClientRect, вызванной с хэндлом нужного диалогового окна. Наложение регионов выполняется функцией CombineRgn, возможные режимы наложения смотрите в официальной документации. Все действия выполняются на этапе инициализации окна по событию WM_INITDIALOG.
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- hRMain dd ? ; Хэндл главного региона окна
- coord RECT ; Координаты окна для вычисления размера региона
- ...
Читать статью целиком »
Просмотров: 7230 | Комментариев: 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
- ...
Читать статью целиком »
Просмотров: 6106 | Комментариев: 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
Читать статью целиком »
Просмотров: 5391 | Комментариев: 11