
Вертикальный скроллер на Ассемблере
Я уже ранее приводил код горизонтального скроллера на Ассемблере, теперь пришло время вертикального скроллера. Такой эффект очень часто используется в различных кейгенах, окнах "О программе", демо-роликах, просмотрщиках текстовых файлов и подобных программах. Код основан на аналогичной процедуре от Av0id, я добавил в него несколько усовершенствований. Для настройки размеров и внешнего вида скроллера в сегменте данных определяются вспомогательные константы и структуры, не описанные в FASM:Code (Assembler) : Убрать нумерацию
- ; Настройки внешнего вида скроллера
- SCROLL_FONT_WIDTH = 8 ; Ширина символов текста
- SCROLL_FONT_HEIGHT = 8 ; Высота символов текста
- SCROLL_WIDTH = 430 ; Ширина окна скроллера
- SCROLL_HEIGHT = 350 ; Высота окна скроллера
- SCROLL_BACKCOLOR = 0808080h ; Цвет фона
- SCROLL_TEXTCOLOR = 000FFFFh ; Цвет текста
- SCROLL_SHADOWCOLOR = 0 ; Цвет тени
- SCROLL_SLEEP = 40 ; Скорость скроллирования
- SCROLL_SHADOW = FALSE ; Рисовать тень TRUE/FALSE
- ; Структуры для создания виртуального BMP-файла
- struct RGBQUAD
- rgbBlue db ?
- rgbGreen db ?
- rgbRed db ?
- rgbReserved db ?
- ends
- struct BITMAPINFO
- bmiHeader BITMAPINFOHEADER
- bmiColors RGBQUAD
- ends
Code (Assembler) : Убрать нумерацию
- section '.data' data readable writeable
- hThread dd ? ; Хэндл потока скроллера
- exit_flag dd ? ; Флаг завершения потока
- active_flag dd ? ; Флаг активности скроллера
- szTerminalFont db 'Terminal',0 ; Шрифт скроллера
- ; Файл с текстом скроллера
- szScrollerText file 'scroller.txt'
- db 0
Запуск скроллера выполняется в отдельном окне, отдельным потоком. При этом свойства окна прописываются в ресурсах, а его размер подгоняется под размер, описанный в настройках скроллера.
Code (Assembler) : Убрать нумерацию
- ...
- ; Инициализация окна скроллера
- cmp [wMsg],WM_INITDIALOG
- je .wminit
- ...
- .wminit:
- ; Флаг завершения потока скроллера
- mov [exit_flag],FALSE
- ; Подогнать размеры окна под размер скроллера
- invoke SetWindowPos,[hWnd],NULL,NULL,NULL,SCROLL_WIDTH,\
- SCROLL_HEIGHT,SWP_NOACTIVATE+SWP_NOZORDER+SWP_NOMOVE
- ; Запустить скроллер
- invoke CreateThread,NULL,NULL,VerticalScrollShadow,\
- [hWnd],NULL,NULL
- ; Сохранить хэндл потока
- mov [hThread],eax
- ; Установить приоритет потока скроллера
- invoke SetThreadPriority,eax,THREAD_BASE_PRIORITY_MAX
Code (Assembler) : Убрать нумерацию
- ;---------------------------------------------------
- ; Процедура вертикального скроллера текста в окне
- ; На основе кода от Av0id
- ;---------------------------------------------------
- proc VerticalScrollShadow hWnd:DWORD
- ; Локальные переменные
- locals
- hDC dd ?
- hCompatDC dd ?
- hCompatDC2 dd ?
- hFont dd ?
- hLen dd ?
- hTextHeight dd ?
- hDIBits dd ?
- hDIBits2 dd ?
- hDIBSection dd ?
- hDIBSection2 dd ?
- hBrush dd ?
- dStep dd ?
- dPos dd ?
- rct RECT
- bmi BITMAPINFO
- endl
- pusha
- xor ebx,ebx
- invoke GetDC,[hWnd]
- mov [hDC],eax
- invoke CreateCompatibleDC,eax
- mov [hCompatDC],eax
- invoke CreateCompatibleDC,[hDC]
- mov [hCompatDC2],eax
- ; Моноширинный шрифт Terminal
- invoke CreateFont,SCROLL_FONT_WIDTH,SCROLL_FONT_HEIGHT,\
- ebx,ebx,FW_NORMAL,ebx,ebx,ebx,OEM_CHARSET,ebx,ebx,\
- ebx,ebx,szTerminalFont
- mov [hFont],eax
- invoke SelectObject,[hCompatDC],eax
- ; Вычислить размеры блока текста
- xor esi,esi
- dec esi
- mov edi,szScrollerText
- invoke lstrlen,edi
- inc eax
- mov [hLen],eax
- mov ecx,eax
- ; Количество строк равно количеству символов переноса строки
- mov al,13
- @@:
- inc esi
- repne scasb
- jz @b
- ; Высота картинки равна количеству строк * высоту шрифта
- xor edx,edx
- mov eax,SCROLL_FONT_HEIGHT
- imul esi
- add eax,SCROLL_HEIGHT
- mov [hTextHeight],eax
- ; Создать виртуальный BMP-файл с нарисованным текстом
- lea edi,[bmi]
- mov [edi+BITMAPINFO.bmiHeader.biSize],sizeof.BITMAPINFOHEADER
- mov [edi+BITMAPINFO.bmiHeader.biWidth],SCROLL_WIDTH
- mov eax,[hTextHeight]
- not eax
- mov [edi+BITMAPINFO.bmiHeader.biHeight],eax
- mov [edi+BITMAPINFO.bmiHeader.biPlanes],1
- mov [edi+BITMAPINFO.bmiHeader.biBitCount],24
- lea eax,[hDIBits]
- invoke CreateDIBSection,[hCompatDC],edi,ebx,eax,ebx,ebx
- mov [hDIBSection],eax
- mov [edi+BITMAPINFO.bmiHeader.biHeight],SCROLL_HEIGHT
- lea eax,[hDIBits2]
- invoke CreateDIBSection,[hCompatDC2],edi,ebx,eax,ebx,ebx
- mov [hDIBSection2],eax
- invoke SelectObject,[hCompatDC],[hDIBSection]
- invoke SelectObject,[hCompatDC2],[hDIBSection2]
- ; Размеры области заливки
- lea edi,[rct]
- mov [edi+RECT.top],0
- mov [edi+RECT.left],0
- mov ecx,[hTextHeight]
- add ecx,SCROLL_HEIGHT
- mov [edi+RECT.bottom],ecx
- mov [edi+RECT.right],SCROLL_WIDTH
- ; Заливка фона
- invoke CreateSolidBrush,SCROLL_BACKCOLOR
- mov [hBrush],eax
- invoke FillRect,[hCompatDC],edi,[hBrush]
- invoke FillRect,[hCompatDC2],edi,[hBrush]
- ; Режим отображения - прозрачный
- invoke SetBkMode,[hCompatDC],TRANSPARENT
- ; Рисовать текст с тенью?
- mov eax,SCROLL_SHADOW
- cmp eax,FALSE
- je @f
- ; Установить координаты сдвига для тени
- mov [edi+RECT.top],1
- mov [edi+RECT.left],2
- ; Нарисовать подложку тени со сдвигом
- invoke SetTextColor,[hCompatDC],SCROLL_SHADOWCOLOR
- invoke DrawText,[hCompatDC],szScrollerText,[hLen],edi,1
- @@:
- ; Координаты вывода нормального текста
- mov [edi+RECT.top],0
- mov [edi+RECT.left],0
- ; Нарисовать основной текст
- invoke SetTextColor,[hCompatDC],SCROLL_TEXTCOLOR
- invoke DrawText,[hCompatDC],szScrollerText,[hLen],edi,1
- mov esi,SCROLL_HEIGHT
- not esi
- .reset:
- mov edi,esi
- .paint:
- ; Отрисовка картинки со сдвигом
- invoke BitBlt,[hCompatDC2],ebx,ebx,SCROLL_WIDTH,SCROLL_HEIGHT,\
- [hCompatDC],ebx,edi,SRCCOPY
- invoke BitBlt,[hDC],ebx,ebx,SCROLL_WIDTH,SCROLL_HEIGHT,\
- [hCompatDC2],ebx,ebx,SRCCOPY
- ; Таймаут
- invoke Sleep,SCROLL_SLEEP
- ; Картинка прокручена до конца?
- inc edi
- mov eax,[hTextHeight]
- sub eax,SCROLL_HEIGHT
- cmp eax,edi
- jz .reset
- ; Флаг выхода установлен?
- cmp [exit_flag],1
- jnz .paint
- .exit:
- ; Прибраться за собой и завершить поток
- invoke DeleteObject,[hBrush]
- invoke DeleteObject,[hDIBSection]
- invoke DeleteObject,[hDIBSection2]
- invoke DeleteObject,[hFont]
- invoke DeleteDC,[hCompatDC]
- invoke DeleteDC,[hCompatDC2]
- invoke ReleaseDC,[hWnd],[hDC]
- invoke ExitThread,ebx
- popa
- ret
- endp
Просмотров: 5307 | Комментариев: 0

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий
Заполните форму для добавления комментария
