Blog. Just Blog

Быстрый поиск

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

Создание диалоговых окон с тенью

03.08.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Сегодня разберем очередное украшательство для ваших программ, а именно тень от диалоговых окон. Обычная тень создается штатными средствами системы, но поддерживается только начиная с Windows XP. Для этого требуется, чтобы стиль окна включал в себя флаг CS_DROPSHADOW, и здесь есть одна тонкость: этот флаг нельзя прописать в ресурсах, а надо устанавливать при инициализации диалогового окна. В обработчике инициализации должен быть такой код:
  1.         ...
  2.         ; Определить константу CS_DROPSHADOW
  3.         CS_DROPSHADOW = 00020000h
  4.         ; Получить текущее значение стиля окна
  5.         invoke  GetWindowLong,[hwnddlg],GCL_STYLE
  6.         ; Добавить к нему атрибут тень
  7.         or      eax,CS_DROPSHADOW
  8.         ; Установить новый стиль окна
  9.         invoke  SetClassLong,[hwnddlg],GCL_STYLE,eax   
  10.         ...
Тут есть плюсы: корректно поддерживаются окна любой нестандартной и сложной формы, а все следующие окна процесса автоматически создаются сразу с тенью. Но есть один странный момент. Несмотря на то, что дочерние окна сперва создаются с корректной тенью, при любом перемещении их над родительским окном тени родительского и дочернего окна сливаются в одну. Пример такого нездорового явления природы показан на скриншоте.

Читать статью целиком »
Просмотров: 6652 | Комментариев: 1

Гиперссылки в диалоговых окнах на Ассемблере

11.07.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Создание текстовой гиперссылки в диалоговом окне, казалось бы, простая задача. Но дело в том, что в Windows по умолчанию нет элементов диалоговых окон, которые бы выполняли роль гиперссылки. Готовых решений на FASM тоже не нашлось, значит придется создавать такой элемент самостоятельно. Сперва определимся с задачами, что нам надо сделать. Должен получиться элемент диалогового окна в виде текста определенного цвета, при наведении на который курсор должен менять свою форму, а цвет изменяться на подсвеченный. При клике на такой элемент должна открываться заданная ссылка. Задачи ясны, начнем их решать. Сперва выберем элемент диалоговых окон из списка стандартных, который и будет использоваться в качестве гиперссылки. Сразу же приходит на ум STATIC. По умолчанию элемент класса STATIC полностью оправдывает свое название и не реагирует практически ни на какие сообщения. Чтобы STATIC принимал движение курсора и нажатия клавиш мышки, его надо описать в ресурсах с флагом стилей SS_NOTIFY.

А как отследить движение курсора только над нашей гиперссылкой? Тут нам на помощь придет такая полезная вещь, как субклассирование. Суть субклассирования проста. С каждым окном связан указатель на оконную процедуру, которая обрабатывает сообщения Windows. Когда система получает сообщение, предназначенное для некоторого окна, она находит адрес оконной процедуры этого окна и вызывает ее. При субклассировании мы заменяем эту процедуру нашей и сохраняем указатель на старую процедуру, чтобы можно было передать ей сообщения для дальнейшей обработки. Это делается функцией SetWindowLong с индексом GWL_WNDPROC на этапе инициализации главного окна:
  1.         ...
  2.         ; Получить хэндл нашего STATIC'а
  3.         invoke  GetDlgItem,[hwnddlg],ID_LINK
  4.         ; Субклассировать гиперссылку и установить собственный
  5.         ; обработчик для STATIC'а
  6.         invoke  SetWindowLong,eax,GWL_WNDPROC,WindowProc
  7.         ; Сохранить адрес предыдущего обработчика
  8.         mov     [OldWndProc],eax
  9.         ...
Теперь напишем процедуру обработки. Тут важно понять основной принцип: при сообщениях, которые мы подавляем или обрабатываем самостоятельно, процедура должна возвращать FALSE, как будто бы их вообще не было. Если сообщение не обрабатывается или оно было модифицировано нашим обработчиком, то его обязательно надо передавать функцией CallWindowProc предыдущему обработчику, адрес которого сохранен при субклассировании. Это можно посмотреть на примере обработчика нашей гиперссылки.

Читать статью целиком »
Просмотров: 6847 | Комментариев: 6

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

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

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


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

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

Читать статью целиком »
Просмотров: 7568 | Комментариев: 11

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

22.06.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Фигурная резьба по деревянным окнам - старинное народное творчество. А в нашем 21-м веке народным творчеством будет резьба по окнам Windows. При умелом использовании это станет стильным украшением для ваших приложений, добавив им привлекательности.

Форма окна определяется особыми структурами, называемыми регионами. Они могут быть прямоугольной формы, закругленной, эллиптической и многоугольной. Весь принцип работы с регионами сводится к следующему. Сперва создается главный регион, равный по размерам основному диалоговому окну, затем создаются дополнительные регионы нужного размера и накладываются на него с нужной битовой маской. Режимы наложения определяют будет ли новый регион удален из основного, или же наоборот добавлен. Размер главного региона лучше всего рассчитывать из результатов функции GetClientRect, вызванной с хэндлом нужного диалогового окна. Наложение регионов выполняется функцией CombineRgn, возможные режимы наложения смотрите в официальной документации. Все действия выполняются на этапе инициализации окна по событию WM_INITDIALOG.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. hRMain  dd ?   ; Хэндл главного региона окна
  5. coord   RECT   ; Координаты окна для вычисления размера региона
  6.         ...
В сегменте данных инициализируется хэндл главного региона окна и структура RECT с координатами диалогового окна, по которым будет рассчитываться размер главного региона.

Читать статью целиком »
Просмотров: 7158 | Комментариев: 1

Всплывающее окно на Ассемблере

26.05.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Всплывающее окно - удобный способ информировать о том, что ваша программа выполнила какое-то действие, не требующее немедленного вмешательства пользователя, но достаточно важное, чтобы он об этом узнал. Это может быть сообщение о завершении закачки файла, получении нового письма, завершении длительных вычислений и т.п. Красивый эффект получается, когда информационное окно плавно выезжает из-под таскбара. Простого перемещения окна тут будет недостаточно, так как придется учитывать положение таскбара и всяких других панелей, которые резервируют под себя часть рабочего стола. Поэтому надо сперва получить размер видимой области экрана с учетом различных панелей инструментов и размеры самого всплывающего окна. Затем окно перемещается по одному пикселу в нужном направлении с учетом положения панелей, а размер его видимой части увеличивается на один пиксел в противоположную сторону. Это делается при помощи функции MoveWindow. Лучше всего сам эффект всплытия реализовать на стадии инициализации окна по сообщению WM_INITDIALOG, но в этом случае придется принудительно показывать окно функцией ShowWindow и обновлять его содержимое функцией UpdateWindow после каждого сдвига. Рекомендуются стили окна без заголовка и поверх всех окон, как сделано в прилагаемом примере. Атрибут прозрачности для всплывающих окон лучше не использовать, так как при анимации появляются заметные искажения.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. coord   RECT    ; Размеры окна
  5. screen  RECT    ; Размеры экрана
  6.  
  7. ; Сегмент кода
  8. section '.code' code readable executable
  9.         ...
  10.         ; Обработчик сообщения WM_INITDIALOG
  11. wminitdialog:
  12.         ; Получить размер рабочей области экрана
  13.         invoke  SystemParametersInfo,SPI_GETWORKAREA,NULL,screen,FALSE
  14.  
  15.         ; Получить размер окна
  16.         invoke  GetClientRect,[hwnddlg],coord
  17.  
  18.         ; Вычислить отступ от правой границы экрана
  19.         mov     eax,[screen.right]
  20.         sub     eax,[coord.right]
  21.         dec     eax
  22.         mov     [screen.right],eax
  23.  
  24.         ; Высота окна
  25.         mov     ecx,[coord.bottom]
  26.         ; Цикл всплытия окна
  27. @@:
  28.         ; Сохранить значение счетчика
  29.         push    ecx
  30.  
  31.         ; Заполняем стек для MoveWindow
  32.         push    TRUE
  33.         mov     eax,[coord.bottom]
  34.         sub     eax,ecx
  35.         push    eax
  36.         push    [coord.right]
  37.         mov     ecx,[screen.bottom]
  38.         sub     ecx,eax
  39.         push    ecx
  40.         invoke  MoveWindow,[hwnddlg],[screen.right]
  41.  
  42.         ; Так как сейчас только инициализация, то придется принудительно
  43.         ; показать окно и обновить его содержимое
  44.         invoke  ShowWindow,[hwnddlg], SW_SHOW
  45.         invoke  UpdateWindow,[hwnddlg]
  46.  
  47.         ; Небольшая пауза
  48.         invoke  Sleep,2
  49.  
  50.         ; Восстановить счетчик
  51.         pop     ecx
  52.         loop    @b
  53.         ...
После полного появления окна нужно решить, каким образом будет выполняться его дальнейшая обработка. Окно можно убрать по таймеру через несколько секунд, скрыть по клику мышкой на нем или подождать другого события, например, нажатия на какую-нибудь кнопку. В любом случае окно можно или просто закрыть, или убрать его с таким же эффектом, только направление движения будет противоположным. Код плавного скрытия всплывающего окна приведен ниже. Подразумевается, что все используемые структуры с размерами после его открытия остались неизменными.

Читать статью целиком »
Просмотров: 6006 | Комментариев: 2

01 ... 64 65 66 67 68 69 70 ... 73
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 3 (0.0147 сек.) / Память: 4.5 Mb
Наверх