Blog. Just Blog

Вывод разноцветного текста в консоли

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Вывод разноцветного текста в консоли
Вывод разноцветного текста в консоли

Давно не обращался к теме консольных приложений, надо бы восполнить этот недостаток. С обычным консольным вводом-выводом вопросов возникнуть не должно, тут ничего сложного нет. А вот какие-нибудь необычные действия с консолью, надеюсь, будут интересными. В оконных приложениях можно менять цвета отдельных элементов, что-то похожее можно делать и в консоли.

В отличие от оконных приложений, где вы можете использовать всю полноту цветовой палитры системы, в консоли так порезвиться не получится. Параметры цвета задаются всего одним байтом, где младшие 4 бита отвечают за цвет текста, а старшие 4 бита - за цвет фона. Соответственно, нам доступны комбинации из 16 цветов фона и 16 цветов текста (CGA-цвета). Для того, чтобы установить цвет для текста в консоли, перед выводом текста используем функцию SetConsoleTextAttribute.
  1.         ...
  2.         ; Задать цвет и фон текста
  3.         ; 4-7 бит - цвет фона
  4.         ; 0-3 бит - цвет текста
  5.         ; остальные биты не используются
  6.         mov     eax,9Eh
  7.  
  8.         ; Установить цвет и фон текста консоли
  9.         invoke  SetConsoleTextAttribute,[stdout],eax
  10.  
  11.         ; Вывести на консоль цветной текст
  12.         invoke  lstrlen,output_string
  13.         invoke  WriteConsole,[stdout],output_string,eax,tmp,NULL
  14.         ...
В пределах строки цвет можно менять сколько угодно раз, при этом часть текста будет выведена одним цветом, а часть - другим.

Ну а раз уж мы затронули тему консоли, то можно попутно рассмотреть еще несколько полезных функций. А именно установку заголовка консольного окна, перемещение курсора по экрану и обработку нажатия клавиш.

По умолчанию в заголовке консольного окна отображается путь до консольного приложения. Эту надпись можно заменить на свою при помощи функции SetConsoleTitle. Измененный заголовок будет сохраняться, пока консольное окно не будет закрыто. Например, если при выполнении нескольких консольных команд в пакетном файле, одна из них поменяет заголовок окна, то он останется до конца выполнения пакетного файла.
  1. ; Сегмент данных
  2. section '.data' data readable writeable 
  3.         ...
  4. szTitle db 'Hello, world!',0 
  5.         ...
  6.  
  7. ; Сегмент кода
  8. section '.code' code readable executable
  9.         ...
  10.         ; Установить заголовок консоли
  11.         invoke  SetConsoleTitle,szTitle
Для перемещения курсора по экрану консоли используется функция SetConsoleCursorPosition. Нулевая координата соответствует левому верхнему углу экрана. Обратите внимание, что структура COORD передается не по указателю, а по значению. В связи с этим, вместо структуры COORD можно использовать значение напрямую из любого регистра размера DWORD. В этом случае координата Y передается в старшем слове, а координата X - в младшем слове. После перемещения курсора следующий вывод в окно консоли будет выполняться уже с новой позиции. Это очень удобно, когда надо отобразить в консоли какой-нибудь динамический процесс, например, процент выполнения задачи.
  1. ; Сегмент данных
  2. section '.data' data readable writeable 
  3.         ...
  4. struct  COORD
  5.         X dw ?
  6.         Y dw ?
  7. ends
  8.  
  9. pos     COORD     ; Структура для установки координат в консоли
  10.         ...
  11.  
  12. ; Сегмент кода
  13. section '.code' code readable executable
  14.         ...
  15.         ; Установка координат через структуру COORD
  16.         mov     [pos.X],5
  17.         mov     [pos.Y],1
  18.         invoke  SetConsoleCursorPosition,[stdout],[pos]
  19.  
  20.         ; Установка координат напрямую через регистр
  21.         ; (Y shl 16) or X
  22.         mov     eax, (1 shl 16) or 5
  23.         invoke  SetConsoleCursorPosition,[stdout],eax
Очень часто после вывода каких-либо данных на экран или до момента закрытия консольного окна требуется получить ответную реакцию пользователя, обычно что-то типа "нажмите любую клавишу для продолжения". Для этого функцией SetConsoleMode консоль переводится в режим немедленного отклика, а затем ожидается ввод одного символа (нажатие любой клавиши). После получения символа программа продолжит выполнение, а именно это нам и нужно. К сожалению, служебные клавиши не перехватываются, только печатные символы.
  1.         ; Получить хэндл стандартного ввода stdin
  2.         invoke  GetStdHandle,STD_INPUT_HANDLE
  3.         mov     ebx,eax
  4.  
  5.         ; Установить режим консоли
  6.         invoke  SetConsoleMode,ebx,NULL
  7.         ; Дождаться нажатия любой клавиши
  8.         invoke  ReadConsole,ebx,buff,1,tmp,0
  9.         ; Первый байт [buff] содержит код нажатой клавиши на тот случай, если
  10.         ; надо анализировать выбор пользователя, например, "Choose [Y]es or [N]o"
В приложении примеры консольных программ с исходными текстами, демонстрирующие эффекты из этой статьи.

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

Color.Console.Demo.zip (7,589 bytes)


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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (27.02.2021 в 00:12):
Ну есть же запуск с преднастройками консоли
Алексей (27.02.2021 в 00:09):
Шрифт бы еще в неё загружать свой :)
ManHunter (29.01.2015 в 11:18):
Это не так. 4 цвета для графики и 16 для текста.
Пруф: https://ru.wikipedia.org/wiki/CGA
Kiry (29.01.2015 в 11:14):
У меня был CGA монитор, там было не более 4 цветов в текстовом режиме. 16 цветов - это VGA
user (26.11.2013 в 01:13):
Я о том и говорю, что ReadConsoleInput позволяет обрабатывать только Ctrl+C и Ctrl+Break, ну и Shift/Alt/Ctrl статусы. Тестовая программка как раз об этом.
ManHunter (26.11.2013 в 00:11):
На самом деле есть замечательные функции FlushConsoleInputBuffer и ReadConsoleInput, при помощи которых, совершенно не напрягаясь, можно перехватить и служебные кнопки.
user (25.11.2013 в 23:59):
Из служебных символов в консоли можно обрабатывать только Ctrl+C и Ctrl+Break, насколько я разобрался. Надыбалась тестовая программка для косольного ввода:
http://rghost.ru/50450092
user (25.11.2013 в 23:45):
Некоторые программы, использующие консоль, пользуются библиотекой PDCURSES.
Там хотя и понятно всё и медленно, зато организована мультиплатформенная поддержка.
Пример такой программы - симпатичный редактор XEDIT-типа - "THE".
==DJ==[ZLO] (25.11.2013 в 19:35):
Зашибись посхалка ))))
Grey (25.11.2013 в 08:31):
Шутник...)))) Цифры больно быстро бегут...

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

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

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