В состав Free Pascal входит целый ряд стандартных модулей, перечислим некоторые из них:
· сrt - подпрограммы модуля обеспечивают контроль над текстовыми режимами экрана, расширенными кодами клавиатуры, цветами, окнами и звуком;
· dos - в модуле находятся подпрограммы взаимодействия с операционной системой и обработки файлов;
· printer - модуль, служащий для программного вывода на принтер;
· strings - модуль обеспечивает поддержку символьных строк, завершающихся нулевым байтом;
· math – модуль содержит много дополнительных математических, тригонометрических и статистических функций;
· graph - в модуле находится библиотека, состоящая из более, чем 50 графических подпрограмм для рисования различных геометрических фигур;
· wincrt – модуль для поддержки терминал подобного текстового окна в экране. При этом не нужно писать специальный код для поддержки окон.
Чтобы использовать любой из этих модулей, его достаточно подключить оператором uses.
В следующем разделе представлены основные возможности модуля crt, позволяющего добавлять программам удобный пользовательский интерфейс.
CRT - стандартный модуль Pascal, в котором содержатся разнообразные средства ввода-вывода. Процедуры и функции CRT, предназначенные для работы с экраном в консольном (текстовом) режиме, помогут вам организовать хороший интерфейс в ваших программах. Кроме процедур и функций любой модуль может также содержать описание типов, константы и переменные, доступные в пользовательской программе (если имя модуля указано в операторе USES).
Для полного описания экранной позиции кроме символа следует задать еще и атрибут, содержащий информацию о цвете символа и фона на экране. Символ и атрибут занимают в памяти по 1 байту. В модуле CRT определена переменная
VAR TextAttr : BYTE,
в которой содержится текущий цвет фона и цвет символов, используемые при выводе на экран процедурами WRITE и WRITELN. Изменив эту переменную, вы задаете новый цветовой атрибут. Цветовой атрибут строится следующим образом : в четырех младших битах хранится цвет символов (от 0 до 15), в следующих трех битах - цвет фона (от 0 до 7), и старший бит отвечает за мерцание. Пусть, например, значение переменной TextAttr равно 237, в двоичной записи - это 1110 1101 (если записывать биты от старшего к младшему). Четыре младших бита (1101) дают цвет символов 13, или LightMagenta - светло малиновый; следующие 3 бита (110) дают цвет фона 6, или Brown - коричневый, старший бит - единичный. Таким образом, будут выводиться мерцающие светло-малиновые символы на коричневом фоне.
Цветовые константы Black ... White определены в CRT точно так же, как и в модуле Graph. Кроме того, определена константа мерцания Blink = 128.
Теперь построим другой цветовой атрибут: мы хоти вывести желтые мерцающие символы на светло-сером фоне. Переменной TextAttr необходимо присвоить значение 14 (желтые символы) +7 (серый фон) * 16 + 128 (мерцание), итого: 14+112+128=254. Столь сложных вычислений легко избежать, если пользоваться 16-ричными числами; наш атрибут в 16-ричном виде записывается как $7E+Blink. Можно обращаться к цвету как по цифровому коду, так и по англоязычному имени.
Структура байта-атрибута показана на рис. Л.1.
Рис. Л.1. Структура байта-атрибута консоли
Рассмотрим некоторые функции и процедуры модуля CRT:
1. FUNCTION KeyPressed : Boolean - возвращает TRUE, если буфер клавиатуры не пуст (все нажатия клавиш во время работы программы накапливаются в специальном участке памяти - буфере клавиатуры, откуда затем поступают в программу). Функция не очищает буфер клавиатуры!
2. FUNCTION ReadKey : Char - считывает символ из буфера клавиатуры, если буфер пуст, то ожидает нажатия клавиши. Эту функцию удобно использовать для организации пауз в программе.
Часто в программах, определяют коды нажатых клавиш. Конструкция repeat ... until является образцом обработки ввода с клавиатуры. Проблема состоит в том, что функция readkey возвращает однобайтовый код клавиши, а ряд клавиш и сочетаний клавиш имеют двухбайтовые коды. С этим связана необходимость второго вызова функции readkey.
3. PROCEDURE Delay(MS: Word) - приостанавливает выполнение программы на MS миллисекунд.
4. PROCEDURE Sound(Hz: Word) - генерирует звуковой сигнал с частотой Hz герц.
5. PROCEDURE NoSound - выключает звуковой сигнал.
6. PROCEDURE Window(X1,Y1,X2,Y2:Byte) - определяет на экране текстовое окно, заданное координатами верхнего левого и нижнего правого углов. Модуль CRT позволяет работать не только со всем экраном, но и с выделенным на нем прямоугольным текстовым, куда направляется весь вывод. Процедура не выполняет никаких видимых действий!
Координата верхнего левого угла экрана равна (1, 1). Минимальный размер текстового окна - один столбец на одну строку. Если какая-либо координата недопустима, то обращение к процедуре Window игнорируется. Заданное по умолчанию окно (1, 1, 80, 25) в режиме 25-и строк и (1, 1, 80, 43) в режиме 43-х строк, что соответствует всему экрану.
7. PROCEDURE TextBackground(Color: Byte) - задает цвет фона для всего последующего вывода.
8. PROCEDURE TextColor(Color: Byte) - задает цвет символов для всего последующего вывода. Процедуры TextBackground и TextColor вместе обеспечивают те же возможности, что и переменная TextAttr.
9. PROCEDURE ClrScr - очищает текущее окно, используя текущий фоновый цвет.
10. PROCEDURE GotoXY(X,Y:Byte) - перемещает курсор в позицию X строки Y текущего окна. Координаты отсчитываются от левого верхнего угла окна.
Все экранные координаты, кроме координат самого окна, являются зависимыми относительно текущего окна. Например, GotoXY(1, 1) всегда будет устанавливать курсор в верхний левый угол текущего окна.
11. FUNCTION WhereX : Byte и
12. FUNCTION WhereY : Byte - возвращают текущие относительные координаты курсора (позицию и строку).
13. PROCEDURE DelLine - удаляет строку окна, в которой находится курсор, все нижние строки автоматически смещаются вверх.
14. PROCEDURE InsLine - вставляет пустую строку перед строкой, в которой находится курсор, все нижние строки автоматически смещаются вниз, и последняя строка окна теряется.
Многие процедуры и функции Crt являются относительными к текущему окну, включая ClrEol, ClrScr, DelLine, GotoXY, InsLine, WhereX, WhereY, Read, Readln, Write и Writeln. В переменных WindMin и WindMax хранятся текущие размеры окна. При обращении к процедуре Window, курсор всегда перемещается в позицию (1,1).
При запуске программы из оболочки Паскаля монитор уже находится в текстовом режиме и устанавливать его не нужно. Тем не менее, существует стандартная процедура TextMode (Mode:integer), устанавливающая текстовый режим с номером Mode. Стандартный цветной текстовый режим 25*80 позиций имеет номер 3, цветной текстовый режим 25*40 позиций - номер 1.
Программа, очищающая экран и печатающая слово ПРИВЕТ! в заданном месте экрана.
Program Primer_crt1;
Uses Crt;
Begin
clrscr;
GotoXY(20, 10);
WriteLn('Привет!');
End.
Пример программы, которая рисует улитку Паскаля в текстовом режиме при помощи символа *.
Program primer_crt2;
Uses Crt;
Const X=40;Y=14;
Var I:Integer;
Begin
ClrScr;
For I:=0 To 200 Do
Begin
GotoXY(X+Round(Sin(I/9)*I/9),Y+Round(Cos(I/9)*I/15));
Write('*');
Delay(1000);
End;
ReadLn;
End.
Пример программы с процедурой Window. В программе создаются произвольного размера окна, которые закрашиваются произвольным цветом. Обратите внимание, что после объявления нового активного окна, процедура ClrScr работает уже для этого окна, а не для всего экрана.
Program Primer_crt3;
Uses Crt;
Var X, Y : byte;
Begin
TextBackground(Black); // цвет фона черный
ClrScr;
Repeat
X:=succ(Random(80)); // начальная координата окна меньше пределов
Y:=succ(Random(25));
Window(X, Y, X + Random(15)+1, Y + Random(10)+1);
TextBackground(Random(16)); // цвет фона окна
Delay(200);
ClrScr;
Until KeyPressed;
End.
Использование звуковых сигналов.
Program Primer_crt4;
Uses Crt;
Var I:Integer;
Begin
For I:=0 To 80 Do
Begin
Sound(200+100*i); {Звук с нарастающей частотой от 200 Гц}
Delay(1000); {задержка}
NoSound; {Выключаем динамик}
End;
End.
Покажем также несколько примеров программ с более серьезным интерфейсом.
Первая программа распознает коды нажатых клавиш, включая коды расширенных клавиш, таких как F1, F2, стрелки направления, Home, End и т.п.
Program Primer_crt5;
uses crt;
var ch : char;
begin
clrscr;
writeln ('Программа выводит коды клавиш;', ' Esc - выход.');
repeat
writeln('Нажмите клавишу:');
ch := readkey; {Ждем ввода символа}
if ch = #0 then {Если нажата спец. клавиша, то функция вернула 0,}
begin
ch := readkey; {и нужно прочитать код символа дополнительно}
writeln('Нажата специальная клавиша с кодом ', ord(ch));
end
else {Иначе если нажата обычная клавиша}
writeln('Нажата клавиша с ASCII-кодом ',ord(ch));
until ch=#27; {27 – код клавиши Escape}
end.
Вторая программа загадает число, а пользователь должен его отгадать.
Program Game;
USES Crt;
VAR X,F : Byte;
S : STRING;
Code : Integer;
Yes : Boolean;
BEGIN
Window(1,1,60,20); // создаем новое окно
TextBackground(7); // серого цвета
ClrScr; {очистим экран}
RANDOMIZE; F:=RANDOM(10); {загадаем число}
Window(26,11,54,13); // создаем еще одно новое окно
TextAttr:=$20; // зеленого цвета
ClrScr; {в новом окне делаем вывод и ввод}
REPEAT
GotoXY(3,2);
WRITE('Введите число от 0 до 9 ');
READLN(S); VAL(S,X,Code);
IF (Code=0)AND(X=F) THEN
BEGIN {правильное число}
ClrScr;
GotoXY(8,2);
WRITE('Вы угадали !!!');
REPEAT UNTIL KeyPressed;
HALT;
END;
{неправильное число}
TextAttr:=$4F+Blink;
ClrScr; Sound(500); GotoXY(11,2);
WRITE('ошибка !'); Delay(500); NoSound;
{запрос на повторение}
TextAttr:=$20; ClrScr; GotoXY(6,2);
WRITE('Сдаетесь ? [Y/N]');
IF ReadKey IN ['Y','y'] THEN Halt;
UNTIL FALSE;
END.
При построении интерфейса необходимо руководствоваться простыми правилами:
· на экране не должно быть "мусора" – используйте процедуру ClrScr;
· пользователь в любой момент работы должен понимать, что от него требуется - выводите подсказки к вопросам;
· неверный ввод данных не должен приводить к аварийному завершению программы – проверяйте и зацикливайте чтение с клавиатуры;
· результаты работы должны выводиться в понятном и аккуратном виде.
Процедура GetTime(var Hour, Minute, Second, Sec100 : Word) - возвращает текущее системное время, установленное в операционной системе.
Процедура GetDate(var Year, Month, Day, DayofWeek : Word) - возвращает текущую системную дату, установленную в операционной системе. Значения DayofWeek: 1 – понедельник, 2 – вторник, 3 - и т.д.
Пример:
GetTime(HH, MM, SS, S100);
Полученное с помощью процедуры GetTime значение времени можно вывести в заданные координаты экрана в виде "Текущее время: HH-часов, MM-минут, SS-секунд".
Program Prim_Dos;
uses crt, dos;
var Hour,minute,second,sec100: word;
begin
clrscr;
textcolor(lightblue);
repeat
gotoxy (1,1);
GetTime (Hour, minute, second, sec100);
writeln ('Текущее время: ',Hour:2, ':', minute:2, ':', second:2);
write ('Текущее время: ',Hour:2, ' часов ', minute:2, ' минут ', second:2, ' секунд');
Delay (1000);
Until keypressed;
end.
Иногда требуется, чтобы программа вывела результаты своей работы на принтер. Для этого в разделе описаний программы следует указать оператор
uses printer;
подключающий стандартную библиотеку для работы с принтером.
При использовании оператора write или writeln необходимо указать символическое имя принтера lst, описанное в библиотеке printer. А точнее, модуль Printer объявляет файловую переменную текстового типа, связанную с портом LPT.
Например, так:
write ('Hello'); // строка 'Hello' выведена на экран
write (lst,'Hello'); // строка ‘Hello’ выведена на принтер
Отличие между write и writeln сохраняется при выводе на принтер - то есть, при использовании writeln позиция печати на принтере будет переведена на следующую строку.
При выводе на печать рекомендуется вставлять программный код, позволяющий проверить, готов ли принтер к печати и удалась ли операция вывода данных на него, с использованием стандартной функции IoResult.