Эффект бегущей строки на Ассемблере
Очередной интересный визуальный эффект для ваших программ - бегущая строка. Обычно подобный эффект используется в различных кейгенах, но вполне может пригодиться и для более мирных приложений. В качестве основы взята ассемблерная библиотека Scroller lib 1.01 от ReWolf / HTBTeam. Изначально она предназначалась для MASM, так что пришлось ее портировать под FASM. В процессе переноса библиотека была немного переработана и дополнена, а также упрощена ее структура и подключение к проектам. Сперва в сегменте данных определяются вспомогательные константы и структура для создания скроллера.Code (Assembler) : Убрать нумерацию
- ; Константы, определяющие режим скроллера
- SCROLL_START = 0 ; Скроллер запущен
- SCROLL_PAUSE = 1 ; Скроллер на паузе
- SCROLL_STOP = 2 ; Скроллер полностью остановлен
- ; Структура для скроллера
- struct SCROLLSTRUCT
- ; Значения заполняются пользователем
- hwDlg dd ? ; Хэндл окна для скроллера
- hFont dd ? ; Шрифт скроллера
- ddWidth dd ? ; Ширина скроллера
- X dd ? ; Координата X
- Y dd ? ; Координата Y
- lpstrText dd ? ; Строка скроллера ASCIIZ
- ddTxtColor dd ? ; Цвет текста скроллера
- ddBkgColor dd ? ; Цвет фона скроллера
- ddSpeed dd ? ; Скорость движения
- dbMode db ? ; Режим скроллера
- ; Внутренние переменные
- ddROP dd ?
- hBkgDC dd ?
- hTxtBmp dd ?
- hTmpBmp dd ?
- hBakTmpBmp dd ?
- hInDC dd ?
- ddHeight dd ?
- ddPos dd ?
- ddTxtWidth dd ?
- ends
После инициализации переменных вызывается основная функция скроллера. Обратите внимание, что скроллер должен быть привязан только к существующему и видимому окну, поэтому в функции выполняется проверка существования родительского окна, а само окно принудительно делается видимым. Принцип работы скроллера в том, что из окна считывается фрагмент заданного размера, текст скроллера преобразуется в картинку, а затем в цикле по ней передвигается "кадр" и накладывается на фрагмент из окна.
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Процедура инициализации и запуска скроллера
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;
- ; Based on Scroller lib v1.01 by ReWolf / HTBTeam
- ; http://rewolf.prv.pl
- ;
- ; Параметры вызова:
- ; lpScrollData - указатель на заполненную структуру SCROLLSTRUCT
- ;-----------------------------------------------------------------------
- proc Scroller lpScrollData:DWORD
- ; Локальные переменные
- local sz_x :DWORD
- local sz_y :DWORD
- local ddLen :DWORD
- local hBkgBrush :DWORD
- local hBkgPen :DWORD
- ; Локальная проекция структуры
- virtual at 0
- scroll SCROLLSTRUCT
- end virtual
- ; Сохранить все регистры
- pusha
- ; Указатель на структуру SCROLLSTRUCT
- mov edi,[lpScrollData]
- ; Родительское окно существует?
- invoke IsWindow,[edi+scroll.hwDlg]
- or eax,eax
- jnz @f
- ; Восстановить все регистры
- popa
- ; EAX = 0, функция завершилась с ошибкой
- xor eax,eax
- ret
- @@:
- ; Сделать окно видимым и обновить его
- invoke ShowWindow,[edi+scroll.hwDlg],SW_SHOW
- invoke UpdateWindow,[edi+scroll.hwDlg]
- ; Получить контекст устройства окна
- invoke GetDC,[edi+scroll.hwDlg]
- mov [edi+scroll.hBkgDC],eax
- ; Режим наложения AND
- mov [edi+scroll.ddROP],SRCAND
- ; Стартовая позиция скроллера = 0
- mov [edi+scroll.ddPos],0
- invoke CreateCompatibleDC,[edi+scroll.hBkgDC]
- mov [edi+scroll.hInDC],eax
- ; Установить шрифт скроллера
- invoke SelectObject,[edi+scroll.hInDC],[edi+scroll.hFont]
- ; Получить длину строки скроллера
- invoke lstrlen,[edi+scroll.lpstrText]
- mov [ddLen],eax
- lea eax,[sz_x]
- invoke GetTextExtentPoint32,[edi+scroll.hInDC],[edi+scroll.lpstrText],\
- [ddLen],eax
- push [sz_y]
- pop [edi+scroll.ddHeight]
- push [sz_x]
- pop [edi+scroll.ddTxtWidth]
- mov eax,[edi+scroll.ddWidth]
- shl eax,1
- add eax,[edi+scroll.ddTxtWidth]
- invoke CreateCompatibleBitmap,[edi+scroll.hBkgDC],eax,\
- [edi+scroll.ddHeight]
- mov [edi+scroll.hTxtBmp],eax
- invoke SelectObject,[edi+scroll.hInDC],[edi+scroll.hTxtBmp]
- invoke SetBkMode,[edi+scroll.hInDC],OPAQUE; TRANSPARENT;
- invoke SetTextColor,[edi+scroll.hInDC],[edi+scroll.ddTxtColor]
- invoke CreateSolidBrush,[edi+scroll.ddBkgColor]
- mov [hBkgBrush],eax
- invoke SelectObject,[edi+scroll.hInDC],eax
- invoke CreatePen,PS_SOLID,1,[edi+scroll.ddBkgColor]
- mov [hBkgPen],eax
- invoke SelectObject,[edi+scroll.hInDC],eax
- mov eax,[edi+scroll.ddWidth]
- shl eax,1
- add eax,[edi+scroll.ddTxtWidth]
- invoke Rectangle,[edi+scroll.hInDC],0,0,eax,[edi+scroll.ddHeight]
- invoke TextOut,[edi+scroll.hInDC],[edi+scroll.ddWidth],0,\
- [edi+scroll.lpstrText],[ddLen]
- invoke SelectObject,[edi+scroll.hInDC],[hBkgPen]
- invoke SelectObject,[edi+scroll.hInDC],[hBkgBrush]
- invoke DeleteObject,[hBkgPen]
- invoke DeleteObject,[hBkgBrush]
- invoke CreateCompatibleBitmap,[edi+scroll.hBkgDC],\
- [edi+scroll.ddWidth],[edi+scroll.ddHeight]
- mov [edi+scroll.hBakTmpBmp],eax
- invoke SelectObject,[edi+scroll.hInDC],eax
- invoke BitBlt,[edi+scroll.hInDC],0,0,[edi+scroll.ddWidth],\
- [edi+scroll.ddHeight],[edi+scroll.hBkgDC],[edi+scroll.X],\
- [edi+scroll.Y],SRCCOPY
- invoke SelectObject,[edi+scroll.hInDC],[edi+scroll.hBakTmpBmp]
- invoke CreateCompatibleBitmap,[edi+scroll.hBkgDC],\
- [edi+scroll.ddWidth],[edi+scroll.ddHeight]
- mov [edi+scroll.hTmpBmp],eax
- ; Запустить основную процедуру скроллера
- xor eax,eax
- push eax
- invoke CreateThread,NULL,NULL,scroll_proc,[lpScrollData],NULL,esp
- pop eax
- ; Обновить родительское окно
- invoke UpdateWindow,[edi+scroll.hwDlg]
- ; Восстановить все регистры
- popa
- ; EAX = 1, функция выполнена успешно
- xor eax,eax
- inc eax
- ret
- endp
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Вспомогательная функция скроллера, напрямую не вызывается
- ;-----------------------------------------------------------------------
- proc scroll_proc lpScrollData:DWORD
- ; Локальная проекция структуры
- virtual at 0
- pscroll SCROLLSTRUCT
- end virtual
- ; Указатель на структуру SCROLLSTRUCT
- mov edi,[lpScrollData]
- .scroll_loop:
- ; Проверить режим скроллера
- cmp [edi+pscroll.dbMode],SCROLL_STOP
- ; Выход
- je .scroll_exit
- ; Если скроллер только создан, то отрисовать его
- cmp [edi+pscroll.ddPos],1
- jbe @f
- ; Выдержать паузу согласно заданной скорости
- invoke Sleep,[edi+pscroll.ddSpeed]
- ; Скроллер приостановлен?
- cmp [edi+pscroll.dbMode],SCROLL_PAUSE
- je .scroll_loop
- @@:
- mov ebx,[edi+pscroll.ddTxtWidth]
- add ebx,[edi+pscroll.ddWidth]
- cmp ebx,[edi+pscroll.ddPos]
- jne @f
- mov [edi+pscroll.ddPos],0
- @@:
- invoke CreateCompatibleDC,[edi+pscroll.hInDC]
- mov esi,eax
- invoke SelectObject,eax,[edi+pscroll.hBakTmpBmp]
- invoke SelectObject,[edi+pscroll.hInDC],[edi+pscroll.hTmpBmp]
- invoke BitBlt,[edi+pscroll.hInDC],0,0,[edi+pscroll.ddWidth],\
- [edi+pscroll.ddHeight],esi,0,0,SRCCOPY
- invoke SelectObject,esi,[edi+pscroll.hTxtBmp]
- invoke BitBlt,[edi+pscroll.hInDC],0,0,[edi+pscroll.ddWidth],\
- [edi+pscroll.ddHeight],esi,[edi+pscroll.ddPos],\
- 0,[edi+pscroll.ddROP]
- invoke BitBlt,[edi+pscroll.hBkgDC],[edi+pscroll.X],\
- [edi+pscroll.Y],[edi+pscroll.ddWidth],[edi+pscroll.ddHeight],\
- [edi+pscroll.hInDC],0,0,SRCCOPY
- invoke DeleteDC,esi
- inc [edi+pscroll.ddPos]
- jmp .scroll_loop
- .scroll_exit:
- ret
- endp
Просмотров: 8433 | Комментариев: 5
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(20.12.2009 в 02:02):
Неплохая, но тоже заточена под MASM
Vovka
(19.12.2009 в 23:44):
Не плохая либа есть от diablo2oo2
http://diablo2oo2.di.funpic.de...scroller.rar
http://diablo2oo2.di.funpic.de...scroller.rar
Isaev
(16.12.2009 в 00:15):
станет совсем прикольный компонент ;)
ManHunter
(15.12.2009 в 21:18):
Пока не знаю, не пробовал. Но думаю, что смогу.
Isaev
(15.12.2009 в 21:08):
приятно двигается
а можешь добавить расплывчатый эффект в по границам строки?
чтобы выезжала и исчезала как будто из тумана (просто градациями яркости)
а можешь добавить расплывчатый эффект в по границам строки?
чтобы выезжала и исчезала как будто из тумана (просто градациями яркости)
Добавить комментарий
Заполните форму для добавления комментария