Лабораторна робота № 3 - Ввід інформації з клавіатури. Обмін інформації з файлами засобами мови Turbo C

Назва роботи: Вивід інформації на екран ПК

Мета роботи: Ознайомитись з можливостями організації виводу інформації на екран ПК.

Загальні положення.

Вивід інформації на екран ПК може виконуватись на рівні:

МS DOS з використанням функцій переривання 21Н;

Безпосереднім доступом до апаратних засобів;

Перший рівень - мобільний, але повільніший. Функції MS DOS для виклику іінформації на екран викликають драйвер консолі ( виконують вивід в спеціальний символьний файл CON ). Якщо в системі інстальований спеціальний драйвер ( наприклад ANSY. SYS ),то можуть використовуватись

Додаткові засоби по керуванні екраном. Суть розширеного керування полягає в передачі драйверу консолі спеціальних керуючих рядків. Драйвер розпізнає початок керуючого рядка по символу 27Н (1ВН).Символи, що передаються за ним на екран розглядаються як параметри команди, яку виконує драйвер. Інші додатні сторони функцій MS DOS:

Автоматичне позиціювання курсора та скролінг (прокрутка) екрану;

Реакція на натискання клавіш Crtl-Break.

Недоліки - неможливість безпосереднього керування курсором та атрибутом символів. На рівні MS DOS працюють функції стандартного виводу Turbo C, їх прототипи розміщені у файлі stdiо. h

Другий рівень - вивід на рівні BIOS дає більш широкі можливості по

Керруванню екраном. Саме ці функції використовуються драйверами MS DOS для виводу інформації на екран. Недоліком функції BIOS є невелика швидкість виводу, що особливо відчувається при роботі в графічних режимах. На рівні BIOS працюють функції консольного виводу Turbo C, їх прототипи розміщені у файлі conio. h.

Третій рівень - використовується у випадках, критичних за швидкістю

Виводу, коли треба виконувати вивід, використовуючи безпосередній доступ до портів відео-пам'яті адаптера. Це дає можливість досягти максимально можливої швидкості виводу, але вимагає максимальних зусиль програмістів. Функції консольного виводу Turbo С можуть за вибором користувача працювати і на самому нижньому рівні, виконуючи доступ до відео-буфера при роботі у текстовому режимі. Вивід на екран засобами BIOS:

Переривання 10Н має в своєму складі декілька функцій для виводу на екран :

АН=09Н - вивід символа із заданим атрибутом в біжучій позицій курсора;

АН=0АН - вивід символа без атрибута в біжучій позиції курсора;

АН=0ЕН - вивід символа без атрибута в біжучій позиції курсора в режимі "телетайп";

АН=13Н - вивід рядка символів з різними додатковими опціями:

Із зсувом курсора та без нього;

Із визначенням атрибута для всього рядка, для кожного символа, а також без визначення атрибута.

Як приклад використання функції АН=09Н можна розглянути функцію

Wert-prn( ) (приклад *L9-2.C*).Корисною для виведення рамок, заповнення областей екрану є функція printche( ) (приклад *L9-3.C*,*L9-4.C*). Ці функції дають майже максимально можливу при використанні BIOS швидкість.

Скролінг. Очищення вікна всього екрану.

Функції АН=06 та 07 переривання 10Н BIOS виконують так званий скролінг (прокрутку) вікна екрану. При виконанні скролінгу на один рядок догори вся інформація у вікні переміщується на рядок догори. Знизу з'являється чистий рядок догори. Знизу з'являється чистий рядок.

Сі-функція scroll( ) виконує вертикальний скролінг вікна екрану, що задається рядком і стовпчиком лівого верхнього, та рядком і стовпчиком правого нижнього кутів вікна. Якщо змінна direction дорівнює UP, то відбувається скролінг на один рядок догори, якщо вона дорівнює DOWN, скролінг на один рядок донизу, якщо ENTIRE - відбувається очищення екрану (приклад *L9-5.C*). Функція expl_win виводить виводить вибухаюче вікно на екран ( приклад *L9-6.C*). Вивід інформації на екран засобами Turbo C.

Turbo C вміщує великий набір функцій вводу-виволу інформації у вікно екрану. Прототипи цих функцій знаходяться безпосередньо в заголовочному файлі соnio. h. На відміну від функцій стандартного вводу-виводу вони дозволяють керувати кольором виводимих символів.

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

Приклад функції горизонтального скролінга текстового вікна на одну позицію вліво або вправо в програмі *L9-10.C*. Використовується функція movetext( ).

Функція файла соnio. h в принципі дозволяють побувати віконний інтерфейс довільної складності, різноманітні системи меню, т. ін. Програма *L9-11.C* працює в графічному режимі 10Н ЕGA та VGA адаптерів. Ця демонстраційна прогама створює на екркані вікно вводу-виводу. Програма приймає з клавіатури ціле число та рядок символів, потім виводить їх на екран. Вікно вводу-виводу займає 25 стовбчиків та 10 рядків у лівому верхньому куті екрану. Попередній вміст екрану зберігається, а перед звертанням програми відновлюється.

Читання інформації з екрану

В практиці програмування необхідність читання вмісту екрана виникає, як правило, в таких випадках:

При організації віконного інтерфесу ;

При побудові програм переносу резидентною програмою тексту в довільний текстовий редактор;

При побудові різноманітних резидентних HELP систем, які видають "підказку" по слову у біжучій позиції курсора (контекстно-чутлива підказка).

Розглянемо приклад Сі-функцій, яка "читає" слово інформації в біжучій позиції курсора. Словом називається довільна послідовність ASCII-символів, що не включає символи-розділювачі. Всі символи-розділювачі розміщають в ACIIZ-рядок, покажчик на початок якого є параметром функції separators. ASCIIZ-рядок - це масив елементів типу char, в кінці якого розміщенний символ ''-нуль-термінатор. Слово з екрана "копіюється" в статичний буфер функції і доповнюється в кінці нуль-термінатором, утворюючи звичайний ASCIIZ-рядок. Покажчик на початок повертається в точку виклику. В змінних на які вказує str та stlob (нумерується від 0 ), значення передаються в рядок та стовбчик на початку слова на екрані. Якщо слово не знайдено, str та stlob зберігають біжучу позицію курсора. Значення покажчика, що повертається функцією, NULL, свідчить про відсутність в біжучій позиції курсора слова. В такому випадку значення рядка та стовпчика з змінних, на які посилаються str та stlob, будуть дорівнювати біжучий позиції курсора.

Алгоритм роботи функції read-str( ) такий. Визначається біжуча позиція курсора. З відеопам'яті зчитується весь рядок символів, в якому розташовується курсор. Потім починається цикл виділення та аналізу слів в рядку. Для "розбору" рядка на слова використовується функція Turbo C виділення лексем strtok ( ).

Якщо біжуче положення курсора попадає на слово, робота функції завершується і в точку виклику передається покажчик на виділене слово. Якщо у біжучій позиції курсора записаний символ розділювач, повертається слово, що знаходиться зліва від позиції курсора. Якщо ж зліва знаходиться ще один символ розділювач, то повертається NULL. Приклад використання функції у файлі *L9-14.C*. Максимально ефективний варіант функції lh-light( ).("перефарбування" рядка або вертикально, або горизонтально) в програмі *L9-15.C*.

Порядок виконання роботи :

В середовищі MS DOS ініціалізувати одну з систем програмування: Turbo

C, Turbo C++, Boorland C++.

Розглянути можливості виводу на екран засобами BIOS, відкомпілювавши та виконавши приклади (Всі приклади з ВООК2).

Розглянути приклади для виконання скролінгу та очищення.

Розглянути засоби Turbo C виводу на екран та читання інформації з екрану.

Результат виконання проекту:

#include <dos. h>

#include <string. h>

#include <conio. h>

#include "screen. h"

//*********************************************************************

Goto_xy(int stroka, int stolb, int page)

{

Unsigned old_ds;

Register max_colons, max_string, cur_pos, ret;

Old_ds = _DS;

_DS = 0x40;

Max_colons = * (char near *) 0x4a;

Max_string = * (char near *) 0x84;

If(stroka <= max_string &;&; stolb <= max_colons)

{

Cur_pos = (stroka << 8) | stolb;

* (unsigned near *)(0x50 + (page << 1)) = cur_pos;

Ret = OK;

}

Else

Ret = BAD_PARAM;

_DS = old_ds; return ret;

}

Void save_cur(struct cursor_pos * work)

{

Register base_adr;

Register offs

Work -> cur_page = *(char far *)MK_FP(0x40,0x62);

Offs = 0x50 + (work -> cur_page << 1);

Work -> row_col= *(unsigned far *)MK_FP(0x40,offs);

Base_adr = *(unsigned far *)MK_FP(0x40,0x63);

Outportb(base_adr++, 14);

Work -> reg_14 = inportb(base_adr--);

Outportb(base_adr++, 15);

Work -> reg_15 = inportb(base_adr);

}

Void rest_cur(struct cursor_pos * work)

{

Register base_adr;

Register offs;

Offs = 0x50 + (work -> cur_page << 1);

*(unsigned far *)MK_FP(0x40, offs) = work -> row_col;

Base_adr = *(unsigned far *)MK_FP(0x40, 0x63);

Outportb(base_adr++, 14);

Outportb(base_adr--, work -> reg_14);

Outportb(base_adr++, 15);

Outportb(base_adr, work -> reg_15);

}

Void cursor(int mode)

{

Static unsigned shape;

If(mode == ON)

{

If(shape)

{

_CX = shape;

Shape = 0;

}

Else

Return;

}

Else

{

Shape = *(unsigned far *)MK_FP(0x40, 0x60);

_CX = 0x2000;

}

_AH = 0x01;

Geninterrupt(0x10);

}

//*********************************************************************

Vert_prn(int stroka, int stolb, char * str, char attr)

{

Register char cur_page;

Union REGS r;

Cur_page = * (char far *) MK_FP(0x40, 0x62);

/*

If(goto_xy(stroka, stolb, cur_page) == BAD_PARAM)

Return BAD_PARAM;

While(*str)

{

/*

*/

R. h. bh = cur_page;

R. h. bl = attr;

R. x. cx = 1;

R. h. ah = 0x09;

R. h. al = *str ++;

Int86(0x10, &;r, &;r);

Stroka++;

If(goto_xy(stroka, stolb, cur_page) == BAD_PARAM)

Return END_OF_SCREEN;

}

Return OK;

}

Hor_prn(int stroka, int stolb, char * str, char attr)

{

Register char cur_page;

Union REGS r;

Cur_page = * (char far *) MK_FP(0x40, 0x62);

If(goto_xy(stroka, stolb, cur_page) == BAD_PARAM)

Return BAD_PARAM;

While(*str)

{

R. h. bh = cur_page;

R. h. bl = attr;

R. x. cx = 1;

R. h. ah = 0x09;

R. h. al = *str ++;

Int86(0x10, &;r, &;r);

Stolb++;

If(goto_xy(stroka, stolb, cur_page) == BAD_PARAM)

Return END_OF_SCREEN;

}

Return OK;

}

//*********************************************************************

Printche(int str, int stolb, char symb, char atr, int n)

{

Register cur_page;

Register max_stolb;

Union REGS r;

Cur_page = * (char far *) MK_FP(0x40, 0x62);

Max_stolb = * (unsigned far *) MK_FP(0x40, 0x4a);

If(goto_xy(str, stolb, cur_page) == BAD_PARAM)

Return BAD_PARAM;

If(max_stolb < (stolb + n - 1))

Return BAD_PARAM;

R. h. ah = 0x09;

R. h. al = symb;

R. h. bh = cur_page;

R. h. bl = atr;

R. x. cx = n;

Int86(0x10, &;r, &;r);

Return OK;

}

//*********************************************************************

Border(int s0, int c0, int s1, int c1, char * title,

Char atr_title, char style[], char atr)

{

Register max_stolb, max_string, s;

Max_stolb = * (char far *) MK_FP(0x40, 0x4a);

Max_string = * (char far *) MK_FP(0x40, 0x84);

If(s0 >= 0 &;&; s0 < s1 &;&; c0 >= 0 &;&; c0 < c1 &;&;

S1 <= max_string &;&; c1 < max_stolb &;&;

((title!= NULL &;&; (c1 - c0) >= strlen(title)) ||

Title == NULL))

{

Printche(s0,c0,style[0],atr,1);

Printche(s0,c0+1,style[1],atr, c1-c0-1);

Printche(s0,c1,style[2],atr,1);

For(s = s0 + 1; s < s1; s++)

{

Printche(s, c0,style[3],atr,1);

Printche(s, c1,style[4],atr,1);

}

Printche(s1,c0,style[5],atr,1);

Printche(s1,c0+1,style[6],atr, c1-c0-1);

Printche(s1,c1,style[7],atr,1);

If(title!= NULL)

Hor_prn(s0, c0+(c1-c0-strlen(title))/2+1, title, atr_title);

Return OK;

}

Else

Return BAD_PARAM;

}

//*********************************************************************

Void scroll(int direction, char l_row, char l_col, char r_row,

Char r_col, char attr)

{

Union REGS r;

If(direction)

{

R. h. al = 1;

R. h. ah = direction;

}

Else

{

R. h. al = 0;

R. h. ah = 6;

}

R. h. ch = l_row; r. h. cl = l_col;

R. h. dh = r_row; r. h. dl = r_col;

R. h. bh=attr;

Int86(0x10,&;r,&;r);

}

//*********************************************************************

#define HOR_STEP 2

#define VERT_STEP 1

#define TIME 150

Int expl_win(char s0, char c0, char s1, char c1, char color,

Char style[], char atr)

{

Int hor_step, vert_step;

Register char max_stolb, max_string;

Register int cur_s0, cur_c0, cur_s1, cur_c1;

Max_stolb = * (char far *) MK_FP(0x40, 0x4a);

Max_string = * (char far *) MK_FP(0x40, 0x84);

If(s0 >= 0 &;&; s0 < s1 &;&; c0 >= 0 &;&; c0 < c1 &;&;

S1 <= max_string &;&; c1 < max_stolb)

{

Hor_step = HOR_STEP;

Vert_step = VERT_STEP;

Cur_s0 = (s1 + s0) >> 1;

Cur_c0 = (c0 + c1) >> 1;

Cur_s1 = cur_s0;

Cur_c1 = cur_c0;

While(cur_c0>c0 || cur_s0>s0 || cur_c1<c1 || cur_s1<s1)

{

Scroll(ENTIRE, cur_s0, cur_c0, cur_s1, cur_c1, color);

If(style!= NULL)

Border(cur_s0, cur_c0, cur_s1, cur_c1, NULL, atr, style, atr);

Cur_c0 -= hor_step;

Cur_c1 += hor_step;

Cur_s0 -= vert_step;

Cur_s1 += vert_step;

Cur_c0 = (cur_c0 < c0)? c0 : cur_c0;

Cur_c1 = (cur_c1 > c1)? c1 : cur_c1;

Cur_s0 = (cur_s0 < s0)? s0 : cur_s0;

Cur_s1 = (cur_s1 > s1)? s1 : cur_s1;

Delay(TIME);

}

Scroll(ENTIRE, cur_s0, cur_c0, cur_s1, cur_c1, color);

If(style!= NULL)

Border(cur_s0, cur_c0, cur_s1, cur_c1, NULL, atr, style, atr);

Return OK;

}

Else

Return BAD_PARAM;

}

//*********************************************************************

H_scroll(int direction, int l_row, int l_col, int r_row,

Int r_col, char *blank_str, char attr)

{

Int ret, position;

L_col ++; l_row ++; r_col ++; r_row ++;

Switch(direction) {

Case LEFT:

If(!(ret=movetext(l_col + 1, l_row, r_col, r_row, l_col, l_row)))

Return ret;

Position = r_col;

Break;

Case RIGHT:

If(!(ret=movetext(l_col, l_row, r_col-1, r_row, l_col+1, l_row)))

Return ret;

Position = l_col;

Break;

}

Vert_prn(--l_row, --position, blank_str, attr);

Return 1;

}

//*********************************************************************

Int hv_light(int s0, int c0, int n, char atr, int mode)

{

Struct cursor_pos old_cursor;

Register char str, col, max_stolb, max_string, cur_page;

Register cur_pos;

_ES = 0x40;

Max_stolb = *(char _es *) 0x4a;

Cur_page = *(char _es *) 0x62;

Max_string = *(char _es *) 0x84;

If(s0 >=0 &;&; c0 >=0 &;&;

S0 <= max_string &;&; c0 <= max_stolb &;&;

((mode == HORIZONTAL &;&; (c0 + n -1) <= max_stolb) |

(mode == VERTICAL &;&; (s0 + n -1) <= max_string)))

{

Save_cur(&;old_cursor);

Cursor(OFF);

Str = s0;

Col = c0;

While(n--)

{

Cur_pos = (str << 8) | col;

* (unsigned _es *)(0x50 + (cur_page << 1)) = cur_pos;

_AH = 0x08;

Geninterrupt(0x10);

_BH = cur_page;

_BL = atr;

_CX = 1;

_AH = 9;

Geninterrupt(0x10);

If(mode == HORIZONTAL)

Col ++;

Else

If(mode == VERTICAL)

Str ++;

Else

Return BAD_PARAM;

}

Rest_cur(&;old_cursor);

Cursor(ON);

Return OK;

}

Else

Return BAD_PARAM;

}

//*********************************************************************

//*********************************************************************

Void main(){

Clrscr();

Vert_prn(2,2,"Vertical",15);

Hor_prn(3,5,"Horisontal",15);

Printche(3, 20, 'x', 14, 5);

Border(2, 27, 15, 38, "Tilte",15, "ЪДїііАДЩ", 7);

Scroll(UP, 1, 2, 3, 3, 1);

Expl_win(10, 5, 15, 20, 1, "ЪДїііАДЩ", 7);

H_scroll(LEFT, 1, 1, 3, 3,"", 4);

//hv_light(3, 22, 2, 4, 0);

Getch();

Char buffer[2048];

Gettext(1, 1, 40, 25, buffer);

Puttext(41, 1, 80, 25, buffer);

Movetext(3, 4,15, 4, 36, 20);

Похожие статьи




Лабораторна робота № 3 - Ввід інформації з клавіатури. Обмін інформації з файлами засобами мови Turbo C

Предыдущая | Следующая