Blog. Just Blog

Вертикальный скроллер на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Я уже ранее приводил код горизонтального скроллера на Ассемблере, теперь пришло время вертикального скроллера. Такой эффект очень часто используется в различных кейгенах, окнах "О программе", демо-роликах, просмотрщиках текстовых файлов и подобных программах. Код основан на аналогичной процедуре от Av0id, я добавил в него несколько усовершенствований. Для настройки размеров и внешнего вида скроллера в сегменте данных определяются вспомогательные константы и структуры, не описанные в FASM:
  1. ; Настройки внешнего вида скроллера
  2. SCROLL_FONT_WIDTH  = 8          ; Ширина символов текста
  3. SCROLL_FONT_HEIGHT = 8          ; Высота символов текста
  4. SCROLL_WIDTH       = 430        ; Ширина окна скроллера
  5. SCROLL_HEIGHT      = 350        ; Высота окна скроллера
  6. SCROLL_BACKCOLOR   = 0808080h   ; Цвет фона
  7. SCROLL_TEXTCOLOR   = 000FFFFh   ; Цвет текста
  8. SCROLL_SHADOWCOLOR = 0          ; Цвет тени
  9. SCROLL_SLEEP       = 40         ; Скорость скроллирования
  10. SCROLL_SHADOW      = FALSE      ; Рисовать тень TRUE/FALSE  
  11.  
  12. ; Структуры для создания виртуального BMP-файла
  13. struct  RGBQUAD
  14.     rgbBlue      db ?
  15.     rgbGreen     db ?
  16.     rgbRed       db ?
  17.     rgbReserved  db ?
  18. ends
  19.  
  20. struct  BITMAPINFO
  21.     bmiHeader     BITMAPINFOHEADER
  22.     bmiColors     RGBQUAD
  23. ends
А также переменные и другие данные, необходимые для его работы:
  1. section '.data' data readable writeable
  2.  
  3. hThread         dd ?    ; Хэндл потока скроллера
  4. exit_flag       dd ?    ; Флаг завершения потока
  5. active_flag     dd ?    ; Флаг активности скроллера
  6.  
  7. szTerminalFont  db 'Terminal',0 ; Шрифт скроллера
  8.                 ; Файл с текстом скроллера
  9. szScrollerText  file 'scroller.txt'
  10.                 db 0
Если в скроллере используется псевдографика, то желательно оставить шрифт "Terminal", а если будет только текст, то можете выбрать любой другой системный шрифт, лишь бы он был установлен у пользователя на компьютере. Текст скроллера можно создавать в любом редакторе, поддерживающем псевдографику. При использовании рамок или рисунков из символов, они обязательно должны быть дополнены пробелами до правой границы текста. Ширина и высота символов задается в настройках, но имейте в виду, что размеры должны поддерживаться свойствами самого шрифта. Поэкспериментируйте.

Запуск скроллера выполняется в отдельном окне, отдельным потоком. При этом свойства окна прописываются в ресурсах, а его размер подгоняется под размер, описанный в настройках скроллера.
  1.         ...
  2.         ; Инициализация окна скроллера
  3.         cmp     [wMsg],WM_INITDIALOG
  4.         je      .wminit
  5.         ...
  6.  
  7. .wminit:
  8.         ; Флаг завершения потока скроллера
  9.         mov     [exit_flag],FALSE
  10.  
  11.         ; Подогнать размеры окна под размер скроллера
  12.         invoke  SetWindowPos,[hWnd],NULL,NULL,NULL,SCROLL_WIDTH,\
  13.                 SCROLL_HEIGHT,SWP_NOACTIVATE+SWP_NOZORDER+SWP_NOMOVE
  14.  
  15.         ; Запустить скроллер
  16.         invoke  CreateThread,NULL,NULL,VerticalScrollShadow,\
  17.                 [hWnd],NULL,NULL
  18.         ; Сохранить хэндл потока
  19.         mov     [hThread],eax
  20.  
  21.         ; Установить приоритет потока скроллера
  22.         invoke  SetThreadPriority,eax,THREAD_BASE_PRIORITY_MAX
А вот и сама процедура скроллера. Принцип ее работы ненамного отличается от горизонтального скроллера. Точно так же текст преобразуется в картинку, а затем на фон из этой картинки в цикле накладывается "кадр" со сдвигом. Если задана тень, то сперва на фон накладывается тот же текст, но темного цвета и со смещением в несколько пикселов для создания нужного визуального эффекта. При достижении конца текста он "перематывается" на начало.
  1. ;---------------------------------------------------
  2. ; Процедура вертикального скроллера текста в окне
  3. ; На основе кода от Av0id
  4. ;---------------------------------------------------
  5. proc  VerticalScrollShadow hWnd:DWORD
  6.  
  7.   ; Локальные переменные
  8.   locals
  9.         hDC           dd ?
  10.         hCompatDC     dd ?
  11.         hCompatDC2    dd ?
  12.         hFont         dd ?
  13.         hLen          dd ?
  14.         hTextHeight   dd ?
  15.         hDIBits       dd ?
  16.         hDIBits2      dd ?
  17.         hDIBSection   dd ?
  18.         hDIBSection2  dd ?
  19.         hBrush        dd ?
  20.  
  21.         dStep         dd ?
  22.         dPos          dd ?
  23.  
  24.         rct            RECT
  25.         bmi            BITMAPINFO
  26.   endl
  27.  
  28.         pusha
  29.  
  30.         xor     ebx,ebx
  31.  
  32.         invoke  GetDC,[hWnd]
  33.         mov     [hDC],eax
  34.         invoke  CreateCompatibleDC,eax
  35.         mov     [hCompatDC],eax
  36.         invoke  CreateCompatibleDC,[hDC]
  37.         mov     [hCompatDC2],eax
  38.  
  39.         ; Моноширинный шрифт Terminal
  40.         invoke  CreateFont,SCROLL_FONT_WIDTH,SCROLL_FONT_HEIGHT,\
  41.                 ebx,ebx,FW_NORMAL,ebx,ebx,ebx,OEM_CHARSET,ebx,ebx,\
  42.                 ebx,ebx,szTerminalFont
  43.         mov     [hFont],eax
  44.         invoke  SelectObject,[hCompatDC],eax
  45.  
  46.         ; Вычислить размеры блока текста
  47.         xor     esi,esi
  48.         dec     esi
  49.         mov     edi,szScrollerText
  50.         invoke  lstrlen,edi
  51.         inc     eax
  52.         mov     [hLen],eax
  53.         mov     ecx,eax
  54.         ; Количество строк равно количеству символов переноса строки
  55.         mov     al,13
  56. @@:
  57.         inc     esi
  58.         repne   scasb
  59.         jz      @b
  60.  
  61.         ; Высота картинки равна количеству строк * высоту шрифта
  62.         xor     edx,edx
  63.         mov     eax,SCROLL_FONT_HEIGHT
  64.         imul    esi
  65.         add     eax,SCROLL_HEIGHT
  66.  
  67.         mov     [hTextHeight],eax
  68.  
  69.         ; Создать виртуальный BMP-файл с нарисованным текстом
  70.         lea     edi,[bmi]
  71.         mov     [edi+BITMAPINFO.bmiHeader.biSize],sizeof.BITMAPINFOHEADER
  72.         mov     [edi+BITMAPINFO.bmiHeader.biWidth],SCROLL_WIDTH
  73.         mov     eax,[hTextHeight]
  74.         not     eax
  75.         mov     [edi+BITMAPINFO.bmiHeader.biHeight],eax
  76.         mov     [edi+BITMAPINFO.bmiHeader.biPlanes],1
  77.         mov     [edi+BITMAPINFO.bmiHeader.biBitCount],24
  78.  
  79.         lea     eax,[hDIBits]
  80.         invoke  CreateDIBSection,[hCompatDC],edi,ebx,eax,ebx,ebx
  81.         mov     [hDIBSection],eax
  82.  
  83.         mov     [edi+BITMAPINFO.bmiHeader.biHeight],SCROLL_HEIGHT
  84.  
  85.         lea     eax,[hDIBits2]
  86.         invoke  CreateDIBSection,[hCompatDC2],edi,ebx,eax,ebx,ebx
  87.         mov     [hDIBSection2],eax
  88.  
  89.         invoke  SelectObject,[hCompatDC],[hDIBSection]
  90.         invoke  SelectObject,[hCompatDC2],[hDIBSection2]
  91.  
  92.         ; Размеры области заливки
  93.         lea     edi,[rct]
  94.         mov     [edi+RECT.top],0
  95.         mov     [edi+RECT.left],0
  96.         mov     ecx,[hTextHeight]
  97.         add     ecx,SCROLL_HEIGHT
  98.         mov     [edi+RECT.bottom],ecx
  99.         mov     [edi+RECT.right],SCROLL_WIDTH
  100.  
  101.         ; Заливка фона
  102.         invoke  CreateSolidBrush,SCROLL_BACKCOLOR
  103.         mov     [hBrush],eax
  104.         invoke  FillRect,[hCompatDC],edi,[hBrush]
  105.         invoke  FillRect,[hCompatDC2],edi,[hBrush]
  106.  
  107.         ; Режим отображения - прозрачный
  108.         invoke  SetBkMode,[hCompatDC],TRANSPARENT
  109.  
  110.         ; Рисовать текст с тенью?
  111.         mov     eax,SCROLL_SHADOW
  112.         cmp     eax,FALSE
  113.         je      @f
  114.  
  115.         ; Установить координаты сдвига для тени
  116.         mov     [edi+RECT.top],1
  117.         mov     [edi+RECT.left],2
  118.  
  119.         ; Нарисовать подложку тени со сдвигом
  120.         invoke  SetTextColor,[hCompatDC],SCROLL_SHADOWCOLOR
  121.         invoke  DrawText,[hCompatDC],szScrollerText,[hLen],edi,1
  122. @@:
  123.         ; Координаты вывода нормального текста
  124.         mov     [edi+RECT.top],0
  125.         mov     [edi+RECT.left],0
  126.  
  127.         ; Нарисовать основной текст
  128.         invoke  SetTextColor,[hCompatDC],SCROLL_TEXTCOLOR
  129.         invoke  DrawText,[hCompatDC],szScrollerText,[hLen],edi,1
  130.  
  131.         mov     esi,SCROLL_HEIGHT
  132.         not     esi
  133.  
  134. .reset:
  135.         mov     edi,esi
  136.  
  137. .paint:
  138.         ; Отрисовка картинки со сдвигом
  139.         invoke  BitBlt,[hCompatDC2],ebx,ebx,SCROLL_WIDTH,SCROLL_HEIGHT,\
  140.                 [hCompatDC],ebx,edi,SRCCOPY
  141.         invoke  BitBlt,[hDC],ebx,ebx,SCROLL_WIDTH,SCROLL_HEIGHT,\
  142.                 [hCompatDC2],ebx,ebx,SRCCOPY
  143.  
  144.         ; Таймаут
  145.         invoke  Sleep,SCROLL_SLEEP
  146.  
  147.         ; Картинка прокручена до конца?
  148.         inc     edi
  149.         mov     eax,[hTextHeight]
  150.         sub     eax,SCROLL_HEIGHT
  151.         cmp     eax,edi
  152.         jz      .reset
  153.  
  154.         ; Флаг выхода установлен?
  155.         cmp     [exit_flag],1
  156.         jnz     .paint
  157.  
  158. .exit:
  159.         ; Прибраться за собой и завершить поток
  160.         invoke  DeleteObject,[hBrush]
  161.         invoke  DeleteObject,[hDIBSection]
  162.         invoke  DeleteObject,[hDIBSection2]
  163.         invoke  DeleteObject,[hFont]
  164.         invoke  DeleteDC,[hCompatDC]
  165.         invoke  DeleteDC,[hCompatDC2]
  166.         invoke  ReleaseDC,[hWnd],[hDC]
  167.         invoke  ExitThread,ebx
  168.  
  169.         popa
  170.         ret
  171. endp
В приложении пример программы с исходным текстом, показывающая вертикальный скроллер. Для большей красоты можно добавить в нее код установки окна по центру экрана, музыкальное сопровождение и другие спецэффекты.

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

Vertical.Scroller.Demo.zip (5,095 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 5208 | Комментариев: 0

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

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

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

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

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