Теперь, когда вы знаете больше об управлении экраном, можно испытать более сложный пример moveadd.c. Вы включите несколько вызовов функций
refresh
и
sleep
в этот пример, чтобы на каждом шаге видеть, как выглядит экран. Обычно программы с использованием библиотеки curses стараются обновлять экран как можно реже, поскольку это не слишком высокопроизводительная операция. Программный код написан с некоторой долей искусственности для обеспечения большей наглядности.
1. Для начала вставьте несколько заголовочных файлов, определите несколько символьных
массивов и указатель на них, а затем инициализируйте структуры библиотеки curses:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <curses.h>
int main {
const char witch_one[] = " First Witch ";
const char witch_two[] = " Second Witch ";
const char *scan_ptr;
initscr;
2. Теперь для трех начальных текстовых фрагментов, которые появляются на экране через определенные интервалы, включите и отключите соответствующие флаги атрибутов;
move(5, 15);
attron(A_BOLD);
printw("%s", "Macbeth");
attroff(A_BOLD);
refresh;
sleep(1);
move(8, 15);
attron(A_STANDOUT);
printw("%s", "Thunder and Lightning");
attroff(A_STANDOUT);
refresh;
sleep(1);
move(10, 10);
printw("%s", "When shall we three meet again");
move(11, 23);
printw("%s", "In thunder, lightning, or in rain ?");
move(13, 10);
printw("%s", "When the hurlyburly's done, ");
move(14, 23);
printw("%s", "When the battle's lost and won.");
refresh;
sleep(1);
3. Действующие лица идентифицированы, и их имена выводятся посимвольно:
attron(A_DIM);
scan_ptr = witch_one + strlen(witch_one) - 1;
while (scan_ptr != witch_one) {
move(10, 10);
insch(*scan_ptr--);
}
scan_ptr = witch_two + strlen(witch_two) - 1;
while (scan_ptr != witch_two) {
move(13, 10);
insch(*scan_ptr--);
}
attroff(A_DIM);
refresh;
sleep(1);
4. В заключение переместите курсор в правый нижний угол экрана, а затем подготовьте и выполните завершение:
move(LINES - 1, COLS - 1);
refresh;
sleep(1);
endwin;
exit(EXIT_SUCCESS);
}
Когда
вы выполните программу, заключительный экран будет выглядеть так, как показано на рис. 6.3. К сожалению, снимок экрана не дает полного впечатления и не показывает курсор, установленный в правом нижнем углу экрана. Эмулятор xterm может быть более подходящей средой для точного отображения программ, чем обычная консоль.
Рис. 6.3
Как это работает
После инициализации некоторых переменных и экрана с помощью библиотеки curses вы применили функции
move
для перемещения курсора по экрану. Посредством функций
attron
и
attroff
вы управляли атрибутами текста, выводимого в заданную точку экрана. Далее перед закрытием библиотеки curses и завершением программа продемонстрировала, как вставлять символы функцией
insch
.
Клавиатура
Наряду с предоставлением интерфейса, облегчающего управление экраном, библиотека curses также предлагает средства, облегчающие управление клавиатурой.
Режимы клавиатуры
Процедуры считывания с клавиатуры управляются режимами. Режимы устанавливаются с помощью следующих функций:
#include <curses.h>
int echo(void);
int noecho(void);
int cbreak(void);
int nocbreak(void);
int raw(void);
int noraw(void);
Функции
echo
и
noecho
просто включают и отключают отображение символов, набираемых на клавиатуре. Оставшиеся четыре функции управляют тем, как символы, набранные на терминале, становятся доступны программе с применением curses. Для того чтобы понять функцию
cbreak
, необходимо иметь представление о стандартном режиме ввода. Когда программа, использующая библиотеку curses, стартует с вызова функции
initscr
, устанавливается режим ввода, называемый режимом с обработкой (cooked mode). Это означает построчную обработку, т.е. ввод становится доступен программе после нажатия пользователем клавиши <Enter> (или <Return> на некоторых клавиатурах). Специальные символы на клавиатуре включены, поэтому набор соответствующих клавиатурных последовательностей может сгенерировать сигнал в программе. Управление потоком, если терминал запускается с терминала, также включено. Вызывая функцию
cbreak
, программа может установить режим ввода
cbreak
, в котором символы становятся доступными программе сразу после их набора, а не помещаются в буфер и передаются программе только после нажатия клавиши <Enter>. Как и в режиме с обработкой, специальные символы клавиатуры действуют, а простые клавиши, например <Backspace>, передаются для обработки непосредственно в программу, поэтому если вы хотите, чтобы нажатие клавиши <Backspace> приводило к привычным действиям, то вы должны запрограммировать их самостоятельно.