Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основи програмування Паскаль.docx
Скачиваний:
51
Добавлен:
12.05.2015
Размер:
511.7 Кб
Скачать

23.2. Стандартні модулі Паскаля

До складу Паскаля входить ряд стандартних модулів, перелічимо деякі з них:

dos- у модулі Dos перебувають підпрограми взаємодії з операційною системою й обробки файлів;

strings- модуль забезпечує підтримку символьних рядків, що завершуються нульовим байтом;

graph- у модулі перебуває бібліотека, що полягає з більш ніж 50 графічних підпрограм для малювання різних геометричних фігур;

crt- підпрограми модуля забезпечують контроль над текстовими режимами екрана, розширеними кодами клавіатури, квітами, вікнами й звуком;

printer- знайомий Вам модуль, що служить для програмного виведення на принтер.

Щоб використовувати кожної із цих модулів, його досить підключити оператором uses.

Далі ми вивчимо основні можливості модуля Crt, що дозволяють додавати до своїх програм зручний користувацький інтерфейс.

24. Модуль crt і створення простих інтерфейсів

Модуль Crtмістить процедури й функції, призначені для роботи з екраном у текстовому режимі. Як і ряд інших стандартних модулів, crt вбудований у компілятор і втримується у файліTurbo.tpl.

Екран у текстовому режимі розбивається на окремі рядки, а кожний рядок - на позиції, причому в кожну позицію може бути поміщений тільки 1 символ з набору ASCII.

Для повного опису екранної позиції слід задати ще й атрибут, що містить інформацію про колір символу й тла на екрані. Символ і атрибут займають у пам'яті по 1 байту. Структура байта-атрибута показана нижче:

Біти

7 6 5 4 3 2 1 0

┌─┬─┬─┬─┬─┬─┬─┬─┐

│М│Ф│Ф│Ф│Ц│Ц│Ц│Ц│

└─┴─┴─┴─┴─┴─┴─┴─┘

Біт 7 управляє мерехтінням символу (символ на екрані мерехтить, якщо він установлений в 1), біти 4-6 містять колір тла ( від 0 до 7 включно), а біти 0-3 - колір символу ( від 0 до 15). Зрозуміло, програмістові звичайно не доводиться заповнювати байт атрибута по битках, для цього є стандартні коди квітів. Основні кольори кодуються цифрами від 0 до 15, причому колір тексту може бути будь-яким, а колір тла - тільки з перших 7 квітів. Перелічимо головні кольори:

0 - чорний (BLACK) 8 - темно-сірий (DARKGRAY)

1 - синій (BLUE) 9 - блакитний (LIGHTBLUE)

2 - зелений (GREEN) 14 - жовтий (YELLOW)

4 - червоний (RED) 15 - білий (WHITE)

7 - ясно-сірий (LIGHTGRAY)

Можна звертатися до кольору як по цифровому коду, так і по англомовному імені.

Звичайно використовувані текстові режими мають 25 рядків і 80 позицій у рядку. Нумерація рядків і позицій починається з 1 і вважається ліворуч праворуч і зверху вниз. Увесь екран у текстовому режимі може бути описаний парою координат (1,1),(80,25). Зверніть увагу на порядок запису - СТОВПЕЦЬ, потімРЯДОК.

Нижче коротко розглянуті основні процедури й функції модуля. Для функцій в описі зазначене ключове слово function.

Позначення:

X,X1,X2 - координати стовпців екрана,

Y,Y1,Y2 - координати рядків екрана,

C - значення кольору.

Особливість модуля Crt у тому, що він дозволяє працювати не тільки з усім екраном, але й з виділеним на ньому прямокутним вікном. При цьому все введення, вивід і 'прокручування' тексту відбуваються в межах вікна. За замовчуванням розміри вікна збігаються з розмірами екрана, але можна явно встановити їхнім звертанням до процедури

Window (X1,Y1,X2,Y2);

де (X1,Y1) і (X2,Y2), відповідно, лівий верхній і правий нижній кут вікна.

Textbackground (Color);- Задає колір тла Color

Textcolor (Color);- Задає колір символів Color

Clrscr;- Очищає поточне вікно кольором тла.

Gotoxy (X,Y);- Установлює курсор у позиціюВІКНАз координатами (X,Y).

Clreol;- Видаляє всі символи від курсору включно до кінця рядка, заповнюючи цю ділянку кольором тла.

Delline;- Видаляє рядок, у якому перебуває курсор.

Insline;- Вставляє порожній рядок на екрані в місці розташування курсору й заповнює її кольором тла.

function Wherex:Char; function Wherey:Char;- Функції повертають, відповідно, що течуть X- і Y-Координати курсору.

Sound (Freq);- включає динамік із частотоюFreqгерц.

Delay (Time);- Задає затримку виконання програмиTimeмиллисекунд (1000мс = 1 секунді). Використовується, зокрема, післяSound, щоб визначити час звучання динаміка.

Nosound;- Виключає динамік. Обов'язково використовується після париSoundіDelay.

function Readkey:Char;- Повертає код символу, прочитаний з буфера клавіатури.

function Keypressed: Boolean;- Повертає TRUE, якщо була натиснута клавіша на клавіатурі ( за винятком допоміжних клавіш Alt, Shift, Ctrl і т.д.).

При запуску програми з оболонки Паскаля монітор перебуває звичайно в текстовому режимі й установлювати його не потрібно. Проте, існує процедура Textmode (Mode:Integer), щовстановлює текстовий режим з номеромMode.

Стандартний кольоровий текстовий режим 25*80 позицій має номер 3, кольоровий текстовий режим 25*40 позицій - номер 1.

Модуль Crt містить також змінні, які можна змінювати відповідно до зазначеного для них типом:

Checkbreak:Boolean;- Якщо TRUE ( за замовчуванням), програма реагує на переривання по комбінації клавіш Ctrl+Break.

Directvideo:Boolean;- Якщо TRUE, процедури Write пишуть безпосередньо у відеопам'ять, не використовуючи операційну систему. Це прискорює вивід, але може використовуватися тільки на повністю Ibm-Сумісних ЕОМ.

Textattr:Integer;- Містить поточний атрибут тексту, сформований за описаними вище правилами.

Приведемо приклад програми, що визначає коди натиснутих клавіш. Конструкція Repeat- Untilу цій програмі є зразком обробки введення із клавіатури. Проблема полягає в тому, щоReadkeyповертає однобайтовый код клавіші, а ряд клавіш і комбінацій клавіш мають двухбайтовые коди – із цим зв'язаний і другий виклик функціїReadkeyу програмі.

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}

Writeln (' До побачення.');

end.

Як правило, у реальних програмах широко використовуються не-буквені клавіші, такі як Enter, F1, ESC і т.д. Довідатися коди клавіш можна з таблиць Ascii-Символів. Наприклад, код клавіші Escape = 27. Для запису клавіатурного коду на Паскалі перед його значенням ставиться символ #, як зроблено в цьому прикладі. Більш докладно про обробку натискань клавіш розказано в Додатку 5. Лістинги 5‑ 8 з Додатка 4 також ілюструє основні аспекти обробки натискань клавіш.

Пр.Ця програма заповнює екран випадковими кольоровими вікнами, а також являє приклад програвання нескладної "музики" через вбудований динамік комп'ютера.

Program Crt_Example; {Приклад використання модуля Crt}

uses Crt; {Описуємо модуль у заголовку програми}

const Minlen=10; {Константи: мінімальна довжина вікна}

Pause=500; { затримка при виведення звуку}

Blink=128; { установка біта миготіння}

var X1,Y1,X2,Y2 :integer; {Змінні: координати вікна}

Background, { колір тла вікна}

Color, { колір тексту}

Freq, { частота звуку}

Setblink :integer; { є/немає миготіння}

procedure Doubleframe (x1,y1,x2,y2:integer; Header: string);

{ Процедура малює подвійною рамкою вікно із заголовком }

{ і підготовляє його внутрішню частину для введення тексту}

{ x1,y1,x2,y2 - координати вікна}

{ header - заголовок вікна}

var i,j: integer;

begin

Window (1,1,80,25); { Дозволяємо весь екран для виведення}

gotoxy (x1,y1); { Ставимо курсор у лівий верхній кут}

write ('╔'); {Малюємо}

for i:=x1+1 to x2-1 do write('═'); {верхній рядок}

write ('╗'); {рамки}

for i:=y1+1 to y2-1 do begin {Перебираємо рядка усередині вікна}

gotoxy (x1,i); write('║'); {Ліва границя вікна}

for j:=x1+1 to x2-1 do write (' '); {Внутрішність вікна - пробіли}

write('║'); {Права границя}

end;

gotoxy (x1,y2); write('╚'); {Аналогічно}

for i:=x1+1 to x2-1 do write('═'); {малюємо нижній рядок}

write('╝'); {рамки}

gotoxy (x1+(x2-x1+1-length(Header)) div 2,y1);

{Ставимо курсор у середину верхнього рядка}

write (Header); {Виводимо заголовок}

Window (x1+1,y1+1,x2-1,y2-1); {Установлюємо поточне вікно усередині рамки}

gotoxy (1,1); {Ставимо курсор у лівий верхній кут нового вікна}

end;

begin {Початок основної частини програми}

Textbackground (BLACK); {колір тла - чорний}

Window (1,1,80,25); {вікно виведення - увесь екран}

Clrscr; {очищаємо екран}

Randomize; {Инициализируем генератор випадкових чисел}

Directvideo:=True; { Дозволяємо писати прямо у відеопам'ять - }

{ тільки для повністю Ibm-Сумісних машин!}

while not Keypressed do begin {Поки не натиснута клавіша,}

{виконується цикл}

x1:= 1 + Random(80-Minlen);

x2:=x1 + Minlen + Random (80-x1-Minlen); {Вибираємо випадкові}

y1:= 1 + Random(25); {координати вікна}

y2:= 1 + y1 + Random (25-y1);

Background:=Random(8); {Вибираємо колір тла з 8 можливих}

Color:=Random(16); {Вибираємо колір тексту з 16 можливих}

Setblink:=Random(2); {Вибираємо установку мерехтіння з варіантів ТАК чи НІ}

Textbackground (Background); {Установлюємо колір тла}

Textcolor(Color+Blink*Setblink); {Колір тексту з урахуванням мерехтіння}

Doubleframe (x1,y1,x2,y2,' Hello! ');

{Малюємо вікно за допомогою процедури}

Background := (Textattr and 112) shr 4;

{ З байта кольору, що втримується в змінній Textattr, виділяємо колір }

{ тла. Операція shr XX зрушує байт вправо на XX біт, а 112 в }

{ двійковій системі це 01110000 (включені біти, відповідальні за тло) }

case Background of { Залежно від кольору тла вибираємо }

{ частоту звучання динаміка }

0: Freq:=262; {Частота ноти До}

1: Freq:=294; { -"- Ре}

2: Freq:=330; { -"- Мі}

3: Freq:=349; { -"- Фа}

4: Freq:=392; { -"- Сіль}

5: Freq:=440; { -"- Ля}

6: Freq:=494; { -"- Си}

7: Freq:=524; { -"- До}

end;

Sound (Freq); {Включаємо динамік}

Delay (Pause); {Чекаємо, поки не мине затримка}

Nosound; {Виключаємо динамік!}

end; {Кінець основного циклу}

Textbackground (BLACK); { Відновлюємо нормальні атрибути тексту - }

Textcolor (LIGHTGRAY); { ясно-сірий на чорному, }

Window (1,1,80,25); { вікно у весь екран, }

Clrscr; { очищаємо екран. }

end. { Кінець програми }

Використання цієї програми на сучасному швидкому процесорі може й не дати Вам насолодитися "музикою" – проблема в реалізації функції Delay, що враховує не реально минулий час у миллисекундах, а "умовне" час, пов'язане з тактовою частотою процесора. Для виправлення ситуації варто було б написати й використовувати власну реалізаціюDelay, прив'язану до функціїGettimeмодуляDos, що дозволяє одержати "абсолютне" системний час у годиннику, хвилинах, секундах і сотих частках секунди. Нижче приводиться одна з можливих версій такої функції з коментарями основних дій і тестом:

uses crt,dos;

function getlonginttime:Longint; {Поверне системний час як Longint}

var Hour,Minute,Second,Sec100: word;

var k,r:longint;

begin

Gettime (Hour, Minute, Second, Sec100);

{Пряме обчислення по формулі Hour*360000+Minute*6000+Second*100+Sec100

не спрацює через неявне перетворення word в longint: }

k:=Hour;

r:=k*360000;

k:=Minute;

Inc (r,k*6000);

k:=Second;

Inc(r,k*100);

Inc(r,Sec100);

getlonginttime:=r;

end;

procedure Mydelay (ms:word); {Коректно працює із затримками до 65 сек.!}

var Endtime,Curtime : Longint;

cor:boolean; {ознака корекції часу з урахуванням переходу через добу}

begin

cor:=false;

Endtime:=getlonginttime + ms div 10;

if Endtime>8639994 then cor:=true;

{Ураховуємо можливий перехід через добу;

23*360000+59*6000+59*100+99=8639999 і відняли 5 мс із обліком

частоти спрацьовування системного таймера BIOS}

repeat

Curtime:=getlonginttime;

if cor=true then begin

if Curtime<360000 then Inc (Curtime,8639994);

end;

until Curtime>Endtime;

end;

var Hour,Minute,Second,Sec100: word;

begin

clrscr;

{Settime (23,59,58,99);}

{якщо раскомментарить – може змінити системний час!}

repeat

Gettime (Hour, Minute, Second, Sec100);

Write (Hour:2,':',Minute:2,':',Second:2,':',Sec100:2,' ');

Mydelay (500);

Gettime (Hour, Minute, Second, Sec100);

Writeln (Hour:2,':',Minute:2,':',Second:2,':',Sec100:2,' ');

until keypressed;

end.

У Додатку 4 наведені також лістинги програм для виведення кодів часто використовуваних клавіш, руху по екрану "прицілу" за допомогою клавіш зі стрілками, а також програма створення нескладного дворівневого меню користувача (лістинги 5-7).