Blog. Just Blog

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

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: 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.         ...
После полного появления окна нужно решить, каким образом будет выполняться его дальнейшая обработка. Окно можно убрать по таймеру через несколько секунд, скрыть по клику мышкой на нем или подождать другого события, например, нажатия на какую-нибудь кнопку. В любом случае окно можно или просто закрыть, или убрать его с таким же эффектом, только направление движения будет противоположным. Код плавного скрытия всплывающего окна приведен ниже. Подразумевается, что все используемые структуры с размерами после его открытия остались неизменными.
  1.         ...
  2.         ; Высота окна
  3.         mov     ecx,[coord.bottom]
  4.         ; Цикл закрытия окна
  5. @@:
  6.         ; Сохранить значение счетчика
  7.         push    ecx
  8.  
  9.         ; Заполняем стек для MoveWindow
  10.         push    TRUE
  11.         push    ecx
  12.         push    [coord.right]
  13.         mov     eax,[screen.bottom]
  14.         sub     eax,ecx
  15.         push    eax
  16.         invoke  MoveWindow,[hwnddlg],[screen.right]
  17.  
  18.         ; Обновить содержимое окна
  19.         invoke  UpdateWindow,[hwnddlg]
  20.  
  21.         ; Небольшая пауза
  22.         invoke  Sleep,2
  23.  
  24.         ; Восстановить счетчик
  25.         pop     ecx
  26.         loop    @b
  27.         ...
В приложении пример программы, показывающей вcплывающее окно в правом нижнем углу экрана. Окно автоматически спрячется по таймеру через 10 секунд или по клику мышкой (обрабатывается сообщение WM_LBUTTONDOWN). Код можно легко доработать, например, чтобы окно выдвигалось справа, а убиралось вниз.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

PopUp.Window.Demo.zip (2,655 bytes)


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 4030 | Комментариев: 2

Метки: Assembler, окна
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (04.06.2009 в 20:08):
Не приходилось.
tester (04.06.2009 в 20:04):
ManHunter тебе не приходилось работать с WinInet API на FASM ? Если можешь напиши плиз статью про upload файлов на FASM.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0034 сек.) / Память: 4.5 Mb
Наверх