Опубликован: 15.11.2010 | Доступ: свободный | Студентов: 643 / 18 | Оценка: 4.00 / 5.00 | Длительность: 17:30:00
Специальности: Программист
Лекция 4:

Вывод на дисплей: Часть III

< Лекция 3 || Лекция 4: 123 || Лекция 5 >
Аннотация: На данной лекции Вы познакомитесь с цветовым оформлением текста и фона в консольных приложениях, с использованием escape-последовательностей и средств задания атрибутов текста в языках программирования.

4.1. Атрибуты символов

Когда дисплей установлен в текстовый режим в любой из видеосистем, каждой позиции на экране отводится два байта памяти. Первый байт содержит номер кода ASCII символа, а второй байт - атрибуты символа. Для указания цветов экрана одни и те же номера кодов используются в бейсике, Си и прерываниях операционной системы (см. таблицу 4.1.).

Таблица 4.1. Обозначения цветов в стандартной трёхбитной палитре
Числ. Значение Цветовой атрибут Символ или фон?
0 Чёрный Символ
1 Синий Символ
2 Зелёный Символ
3 Циан (голубой) Символ
4 Красный Символ
5 Пурпурный Символ
6 Коричневый Символ
7 Светло-серый Символ
8 Тёмно-серый Символ
9 Светло-синий Символ
10 Светло-зелёный Символ
11 Светло-голубой Символ
12 Светло-красный Символ
13 Светло-пурпурный Символ
14 Жёлтый Символ
15 Белый Символ
0 Чёрный Фон
16 Синий Фон
32 Зелёный Фон
48 Циан (голубой) Фон
64 Красный Фон
80 Пурпурный Фон
96 Коричневый Фон
112 Светло-серый Фон
128 Мигание Символ
Примечание: Атрибут = Символ+Фон (+ Мигание)

Младшие четыре бита байта атрибутов устанавливают цвет самого символа (бит 3 включает высокую интенсивность цвета). Следующие три бита устанавливают фон символа, и при обычных обстоятельствах старший бит включает и выключает мигание. Образование шестнадцати цветов из 4-х бит проиллюстрировано в таблице 4.2.

Таблица 4.2. Образование 16 цветов из 4-х бит
Сопоставление кодов цветов экрана в 16-ти цветной палитре
Канал Интенсивность
Красный Зелёный Синий Низкая (0) Высокая (1)
0 0 0 Чёрный (0) Серый (8)
0 0 1 Синий (1) Светло-синий (9)
0 1 0 Зелёный (2) Светло-зелёный (10)
0 1 1 Циан (3) Светлый циан (11)
1 0 0 Красный (4) Ярко-красный (12)
1 0 1 Магента (5) Светлая магента (13)
1 1 0 Коричневый (6) Жёлтый (14)
1 1 1 Белый (7) Ярко-белый (15)

4.1.1. Реализация на ассемблере

Прерывания DOS и BIOS предоставляют очень скудные возможности для работы с цветным текстом. Только функция 9 прерывания 10H принимает байт атрибутов при выводе символа. Функция 0AH прерывания 10H выводит символ без указания цвета - он принимается равным цвету по-умолчанию. Функция 0DH прерывания также оставляет нетронутым байт атрибутов.

Функция вывода на экран DOS прерывания 21H всегда выводит белые символы на чёрном фоне. Единственный способ обойти это ограничение - использовать escape-последовательности (см. таблицу 2.2).

Приведём примеры на языке ассемблера вывода сначала обычной строки (белым по чёрному), а затем надпись: "Внимание!" жёлтым цветом на красном фоне.

Пример 4.1.

; --- в сегменте данных
STRING_01	DB	'Я хочу обратить Ваше',0AH,0DH,'$'
STRING_02	DB	'Внимание!$'
NORM_COLOR	DB	27, '[0m$'
ATTENT_COLOR	DB	27, '[1;33;41m$'
CLEAR_COLOR	DB	27, '[0m$'
; --- в сегменте кода
; --- вывод строк
	MOV AH, 9	; функция вывода страницы
	LEA DX, NORM_COLOR	; Обычный цвет
	INT 21H
	LEA DX, STRING_01	; Первая строка
	INT 21H
	LEA DX, ATTENT_COLOR	; Выделение цветом
	INT 21H
	LEA DX, STRING_02	; Вторая строка
	INT 21H
	LEA DX, CLEAR_COLOR	; Сброс атрибутов текста
	INT 21H

Смотри Листинг программы ex04001.asm

4.1.2. Реализация на языках Си

В стандарте на язык Си (ANSI C) нет функций для работы с цветом. Вместо этого рекомендуется использовать escape - последовательности, при условии, что у Вас в системе установлен драйвер ANSI.SYS

В этом случае пример 4.1. запишется следующим образом:

Пример 4.2.

/* ex04002.c */
/* Вставка заголовочных файлов */
#include <stdio.h>
#include <conio.h>
/* описание констант */
const char NORM_COLOR[] = "\x1b[0m"; //Нормальный режим
const char ATTENT_COLOR[] = "\x1b[1;33;41m"; // Выделение цветом
/* Основная программа */
void main( void )
{
/* Определение временной переменной */
	char  cJunk;
/* Вывод строк */
	puts( NORM_COLOR );
	puts( "\nЯ хочу обратить Ваше" );
	puts( ATTENT_COLOR );
	puts( "Внимание!\x1b[0m" );
/* Завершение работы программы */
	cputs( "Press key Enter to exit...\r\n" );
	cJunk = getche();
}
/* Конец программы */

Ниже рассмотрены некоторые функции для "цветного" вывода средствами Turbo C++ и SPHINX C--.

ФУНКЦИЯ TEXTATTR
ОПИСАНА В: <conio.h> (содержит только прототип);
СИНТАКСИС:
void textattr( newattr );
int newattr;
НАЗНАЧЕНИЕ: Устанавливает текстовые атрибуты;
ОПИСАНИЕ: textattr позволяет устанавливать цвет фона и цвет символов одновременно за один вызов. (Обычно вы устанавливаете атрибуты с помощью textcolor и textbackground );

Эта функция не относится к символам, находящимся в текущий момент на экране; она относится только к тому, что отображается функциями (такими как cprintf ) выполняющими вывод в текстовом режиме, после того, как была вызвана функция textattr.

Информация цвета кодируется в параметре newattr следующим образом (смотри рисунок 4.1):

Расшифровка байта атрибута символа при консольном выводе

Рис. 4.1. Расшифровка байта атрибута символа при консольном выводе

В этом 8-битном параметре newattr:

  • ffff - 4-битный цвет символов (1 - 15)
  • bbb - 3-битный цвет фона (1 - 7)
  • B - бит мигания.

Если бит мигания включён, то символ будет мигать. Это можно осуществить путём добавления константы BLINK в атрибут. Если вы используете символьные цветовые константы, определённые в conio.h для создания текстовых атрибутов с помощью textattr, запомните следующие ограничения на цвет фона:

  1. Вы можете выбрать только первые 8 цветов для фона;
  2. Вы должны сдвинуть выбранный цвет фона влево на 4 бита для перемещения его в правильную битовую позицию.
Таблица 4.3. Символьные константы в таблице
Константы для атрибутов текста, определённые в <conio.h>
Константа Перевод Числ. Значение Для символов или фона?
BLACK Чёрный 0 оба
BLUE Синий 1 оба
GREEN Зелёный 2 оба
CYAN Циан (голубой) 3 оба
RED Красный 4 оба
MAGENTA Пурпурный 5 оба
BROWN Коричневый 6 оба
LIGHTGRAY Светло-серый 7 оба
DARKGRAY Тёмно-серый 8 для символов
LIGHTBLUE Светло-синий 9 для символов
LIGHTGREEN Светло-зелёный 10 для символов
LIGHTCYAN Светло-голубой 11 для символов
LIGHTRED Светло-красный 12 для символов
LIGHTMAGENTA Светло-пурпурный 13 для символов
YELLOW Жёлтый 14 для символов
WHITE Белый 15 для символов
BLINK Мигание 128 для символов

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет;
ПЕРЕНОСИМОСТЬ: textattr работает только на IBM PC и совместимых системах;

ФУНКЦИЯ TEXTCOLOR
ОПИСАНА В: <conio.h> (содержится прототип функции);
СИНТАКСИС:
void textcolor( newcolor);
int newcolor;
НАЗНАЧЕНИЕ: Устанавливает цвет символов в текстовом режиме;
ОПИСАНИЕ: textcolor выбирает цвет символа. Эта функция оказывает влияние на функции, производящие прямой вывод на экран в текстовом режиме. Вы можете выбрать цвет, используя символьную константу, определённую в conio.h. Если вы используете эту константу, вы должны включить файл conio.h ;

Эта функция не относится к символам, находящимся в текущий момент на экране; она относится только к тем символам, которые выводятся функциями (такими как cprintf ) в текстовом режиме, осуществлявшим вывод на дисплей после вызова textcolor.

Следующая таблица отображает возможные цвета (как символьные константы ) и их числовые значения (Таблица 4.4.).

Таблица 4.4. Константы возможных цветов символов.
Константы для атрибутов текста, определённые в <conio.h>
Константа Перевод Числ.знач.
BLACK Чёрный 0
BLUE Синий 1
GREEN Зелёный 2
CYAN Циан (голубой) 3
RED Красный 4
MAGENTA Пурпурный 5
BROWN Коричневый 6
LIGHTGRAY Светло-серый 7
DARKGRAY Тёмно-серый 8
LIGHTBLUE Светло-синий 9
LIGHTGREEN Светло-зелёный 10
LIGHTCYAN Светло-голубой 11
LIGHTRED Светло-красный 12
LIGHTMAGENTA Светло-пурпурный 13
YELLOW Жёлтый 14
WHITE Белый 15
BLINK Мигание 128

Вы можете сделать символы мигающими, добавляя BLINK к цвету символов. Встроенная константа BLINK предназначена для этой цели. Например:

textcolor(CYAN+BLINK);

Замечание. Некоторые мониторы не определяют интенсивность сигнала, используемую для создания восьми "light" (светлый) цветов (8-15). На таких мониторах светлые цвета будут изображаться как их "тёмные" эквиваленты (0-7). Аналогично, системы, которые не отображают цвет, используют эти номера как оттенки одного цвета, особые образцы или особые атрибуты (такие как подчёркивание, полужирный шрифт, курсив и т.п.). То, что вы увидите при этом на экране, зависит от оборудования.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет;
ПЕРЕНОСИМОСТЬ: Только на IBM PC и совместимых компьютерах. Соответствующая функция существует в Turbo Pascal;

ФУНКЦИЯ TEXTBACKGROUND
ОПИСАНА В: <conio.h> (содержит прототип);
СИНТАКСИС:
void textbackground( newcolor);
int newcolor;
НАЗНАЧЕНИЕ Выбирает новый цвет фона для текста;
ОПИСАНИЕ: textbackground выбирает цвет фона в текстовом режиме. Эта функция работает только для функций, осуществляющих примой вывод на экран в текстовом режиме. newcolor определяет новый цвет фона. Вы можете определить его как целое (от 0 до 7) или как одну из символических констант, определённых в файле conio.h. При использовании символьных констант необходимо включить файл conio.h ;

Эта функция не относится к символам, находящимся в текущий момент на экране; она относится только к тем символам, которые выводятся функциями (такими как cprintf ) в текстовом режиме, осуществлявшим вывод на экран после вызова этой функции.

Символьные константы в таблице 4.5:

Таблица 4.5. Символьные константы цветов фона консоли
Константы для атрибутов текста, определённые в <conio.h>
Константа Перевод Числ.знач.
BLACK Чёрный 0
BLUE Синий 1
GREEN Зелёный 2
CYAN Циан (голубой) 3
RED Красный 4
MAGENTA Пурпурный 5
BROWN Коричневый 6
LIGHTGRAY Светло-серый 7

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет;
ПЕРЕНОСИМОСТЬ: Только с IBM PC и совместимыми компьютерами. Соответствующая функция существует в Turbo Pascal;

Пример 4.3.

Использование функций управления атрибутами символов textcolor и textbackground.

/* ex04003.c  */
/* Работает только в системе Borland C/C++ 3.10 */
/* Вставка заголовочных файлов */
#include <conio.h>
/* Основная программа */
void main( void )
{
/* Определение временной переменной */
	char  cJunk;
/* Вывод строк */
	textcolor( LIGHTGRAY); textbackground( BLACK );
	cputs( "\r\nЯ хочу обратить Ваше\r\n" );
	textcolor( YELLOW); textbackground( RED );
	cputs( "Внимание!" );
	textcolor( LIGHTGRAY); textbackground( BLACK );
/* Завершение работы программы */
	cputs( "\r\n\r\nPress key Enter to exit...\r\n" );
	cJunk = getche();
}
/* Конец программы */

4.1.3. Реализация в оболочке DOS Command Shell и NDOS

В командной оболочке NDOS есть штатная функция: be, с помощью которой можно менять цвет выводимых символов и их фон. Её синтаксис следующий:

be "команда" "опции и параметры"

а также

be "имя batch-файла".dat

Все команды и опции команды be приведены в приложении №1 (пункт 4.4 данной лекции). Здесь же приведём пример batch файла, реализующий пример 4.3.:

Пример 4.4. Файл ex04005.dat

cls white on black
rowcol 1, 1 "Я хочу обратить Ваше"
rowcol 2, 1 "Внимание!" bright yellow on red

Примечание: Этот файл запускается из командной строки командой:

Пример 4.5

be ex04005.dat

4.1.4. Реализация на языках Perl и Python

Вывод текста с "нестандартными" атрибутами на языках Perl и Python не возможен.

4.1.5. Реализация на языке Prolog

Вывод текста с атрибутами цвета на языке ПРОЛОГ осуществляется с использованием предиката attribute, который может читать и устанавливать текстовый атрибут;

Приведём синтаксис предиката attribute

ФУНКЦИЯ: attribute
СИНТАКСИС: attribute(Attr), где Attr - атрибут символа (целое число);
НАЗНАЧЕНИЕ: Устанавливает или выдаёт текущий атрибут символа;
ОПИСАНИЕ: attribute устанавливает или считывает текущий атрибут вывода. Вывод при помощи write или writef даёт отображение экрана с этим атрибутом. Каждое окно имеет свой атрибут вывода. Когда вы создаёте окно, атрибут вывода автоматически принимает значение атрибута окна, но вы можете изменить его предикатом attribute ;
ШАБЛОНЫ: (i) (o) ;
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Всегда успех;
ОШИБКИ: Никогда не даёт;

Пример 4.3, записанный на языке ПРОЛОГ, будет выглядеть следующим образом:

Пример 4.6.

/* Файл ex04006.pro */
domains
/* Описываем переменные */
	CNorm_color= char
predicates
	attent
	norm_color
clauses
/* Определяем правила */
norm_color :- attribute( '\07' ).
attent :- attribute( '\78' ), nl, write( "Внимание!" ).
goal
/* Вывод нормального текста */
	norm_color, nl,
	write( "Я хочу обратить Ваше" ),nl,
/* Вывод текста с изменёнными атрибутами */
	attent,
/* Возвращение нормальных атрибутов */
	norm_color, nl,
/* Вывод завершающей надписи */
	write( "Press key Enter to exit..." ), readchar( _ ).
/* Конец программы */

4.2. Escape-последовательности

Как Вы, наверное, уже уяснили то, что основным способом манипуляции положением позиции курсора, сменой атрибутов текста при выводе на экран является использование так называемых escape-последовательностей. Наиболее широко их применяют в "консольных" приложениях MS-DOS и UNIX, но часто используют и в других операционных системах. Эти последовательности стандартизированы американским национальным институтом стандартов (ANSI). Сводку используемых при выводе на экран escape - последовательностей см. в таблице 2.1.

Для поддержки escape- последовательностей в операционных системах MS-DOS, Windows 9x/ME необходимо в файле CONFIG.SYS загрузить драйвер ANSI.SYS, при помощи директив DEVICE или DEVICEHIGH. В остальных операционных системах поддержка расширений ANSI включена по-умолчанию (в реестре и файлах конфигурации). Если escape- последовательности всё же не работают, смотрите настройки Вашего компьютера (в файлах конфигурации и в реестре).

4.3. Резюме

После прочтения последних трёх лекций Вы уяснили, каким образом символьные данные выводятся на дисплей с использованием "функций среднего уровня". Материал может показаться Вам не актуальным - ведь Вы уже привыкли работать в "оконном интерфейсе", в котором шрифтовое и абзацное оформление текста намного богаче. Однако если Вы хотите делать свои консольные приложения (а вы их обязательно будете делать в первую очередь) хотя бы чуть-чуть более привлекательными, чем это предоставляют стандартные потоки вывода на дисплей, Вы обязательно обратитесь к этим функциям.

Кроме того, Вы ознакомились с принципиально важными функциями для вывода текста на экран, имеющие при консольном выводе не меньшее значение, чем функции манипулирования контекстом Windows, о котором речь пойдёт в последующих лекциях.

< Лекция 3 || Лекция 4: 123 || Лекция 5 >
Дмитрий Карпов
Дмитрий Карпов
Россия, Нижний Новгород
Олег Корсак
Олег Корсак
Латвия, Рига