
LRP2
.pdfмость выдачи сообщений пользователю по ходу решения задачи (подсказки, предупреждения,сообщения об ошибках),которые покрывают содержимое экрана( буквально "всплывают"на экране ) и после реакции пользователя ( нажатия клавиши ) окно исчезает и экран восстанавливается.Такая организация получила название всплывающего окна.Подобный механизм но более сложная организация используется при разработке исчезающих меню.
При использовании стандартных меню экран очищается или сдвигается, и появляется меню. Когда выбор сделан, экран опять очищается или сдвигается и программа продолжается. Выбор выполняется по номеру позиции.
Когда используется исчезающее или иерархическое меню, то оно покрывает прямо содержимое экрана. После выбора режима, экран возвращается в предыдущее состояние. Вы выбираете нужный режим из меню, используя клавиши управления курсором для передвижения подсвеченного поля и клавишу Ввод. Обычно текущее поле показывается в инверсном виде. Основная разница между стандартными меню и исчезающими и иерархическими меню в том, что стандартное меню прерывает программу. Исчезающие и иерархические меню только приостанавливает текущие действия программы.
Разница между исчезающими и иерархическими меню проста. Только одно исчезающее меню может быть на экране в данный момент времени. Оно используется когда меню имеет только один уровень в глубину, это бывает, когда выбор из меню не имеет подвыборов. С другой стороны несколько иерархических меню могут быть активны одновременно. Они используются когда выбор из одного меню может потребовать использования другого меню для определения некоторых альтернатив.
Имеется три способа доступа к видеоадаптеру. Первый это через прерывание ДОС, которое достаточно медленно для исчезающего меню. Второй - это через процедуры BIOS, которые быстрее, и на быстродействующих машинах, таких, как AT или PS/2 достаточно быстры, если меню не велики. Третий способ - это чтение и запись прямо в видео память, что происходит очень быстро, но требует большей работы от вас. Здесь два разных подхода в видеопроцедурах. Один использует BIOS, а другой прямой доступ к видеопамяти.
3.1. Доступ к экрану через BIOS.
Из-за того, что исчезающие и иерархические меню должны сохранять информацию с того места экрана, на котором они расположены, и восстанавливать его после выбора, вы должны иметь процедуры, которые сохраняют и загружают часть экрана. Метод сохранения и восста-
41
новления части экрана, рассматриваемый в этом разделе связан с вызовами двух встроенных в BIOS функций, которые читают и записывают символы на экран.
Как вы знаете, вызовы BIOS могут быть очень медленными. Однако, они (более или менее) гарантируют работу на любом компьютере, который имеет BIOS, совместимый с IBM, даже если аппаратура экрана другая. Однако, использование прямого доступа к видеопамяти снижает в некоторой степени переносимость, так как требуется 100% совместимость с IBM PC. Программы меню, основанные на BIOS следует использовать в применениях, которые требуют большей мобильности.
3.2.Сохранение части экрана.
Для сохранения содержимого экрана, должно быть прочитано и запомнено текущее значение каждой позиции экрана. Для считывания символа с определенной позиции экрана, используется прерывание 16, функция 8, которая возвращает символ и связанный с ним атрибут текущей позиции курсора. Для считывания символа с определенного места экрана, вы должны иметь способ установки курсора. Для этого используют прерывание 16, функцию 2 с координатой столбца в DL и координатой ряда в DH. Видеостраница задается в BH (используется страница 0 по умолчанию).
Прерывание 16, функция 8 возвращает символ из текущей позиции курсора в AL и его атрибут в AH.
3.3.Восстановление экрана.
Восстановление экрана после реакции пользователя при разработке окон или после сделанного выбора из меню, заключается просто в записи предварительно запомненной информации назад в видеопамять. Для того, чтобы сделать это, используйте прерывание 16, функцию 9, которая требует, чтобы символ был в AL, атрибут в BL, видеостраница в BH, а количество записываемых символов в CX (в нашем случае
1).
3.4.Создание исчезающих меню.
Функции, создающей исчезающее меню, должна быть передана некоторая информация. Во-первых,это список предоставляемых меню режимов. Поскольку в меню передаются высвечиваемые строки, то простейший путь передачи списка строк в функцию - помещение их в двумерный массив и передача указателя на массив. Как утверждалось ранее, значение меню может быть выбрано передвижением освещенной области на нужное поле и нажатием ВК.
42
Функция должна также знать как много режимов в меню, и поэтому это число должно быть передано ей. Она должна также знать где расположить меню, то есть нужны координаты X и Y. Наконец, в некоторых ситуациях может быть желательным помещать меню в рамку, а в других - нет. Поэтому должно быть передано значение рамка включена /выключена.
Функция menu делает следующее:
#Сохраняет область экрана под меню
#Высвечивает рамку, если надо
#Высвечивает меню
#Получает ответ пользователя
#Восстанавливает экран в исходное состояние
Две из этих целей были описаны в предыдущем разделе.
3.5.Высвечивание меню.
Для того, чтобы высветить меню, необходимо помнить, что menu получает указатель на массив указателей на строки. Для высвечивания отдельных строк вы просто индексируете указатель, как массив. Каждый элемент в массиве является указателем на соответствующий элемент меню.
3.6.Высвечивание рамки.
Если нужна рамка, то можно воспользоваться программой для вывода рамки вокруг меню с заданными координатами левого верхнего и правого нижнего углов. Она используют символы, которые являются частью стандартного набора символов на машинах, совместимых с IBM. Если вы хотите, можете выбрать другие.
3.7.Ввод выбора пользователя.
Как утверждалось, пользователь может вводить с помощью клавиш СТРЕЛКА ВНИЗ и СТРЕЛКА ВВЕРХ может переместить освещение на строку и нажать Ввод для ее выбора, (Обычно освещение строки выполняется в инверсном режиме.) Освещенную строку также можно передвигать пробелом. Второй способ это нажатие клавиши, связанной с выбором. Функция get_resp(), показанная здесь, достигает этих целей.
Когда menu начинает выполняться, освещается первое значение меню.
Клавиша ESCAPE используется для окончания работы с меню. Значение ESC 27. После этого программа входит в цикл, ожидающий дейс-
43
твий пользователя. Она использует функцию определения факта нажатия и анализ кода нажатия клавиши, а затем считывания этой клавиши.Необходимо учесть,что если нажата символьная клавиша, то символ помещается в младшие 8 бит, а старшие 8 бит равны 0. Однако, если нажата специальная клавиша, такая, как стрелка, младший байт равен 0, а старший содержит ASCII код позиции клавиши. Коды ASCII для стрелки вверх и стрелки вниз равны 72 и 80 соответственно. А для стрелки вправо и стрелки влево 77 и 75 соответственно.
Каждый раз при нажатии стрелки освещенная опция переходит в нормальное изображение, а следующая - освещается,при этом модифицируется переменная n_pos,которая хранит текущий номер позиции меню.Нажатие стрелки вниз, в момент освещения крайней нижней позиции, означает возвращение к первому значению. То же самое, но наоборот происходит когда нажимается стрелка вверх при освещенной первой строке.
3.8. Прямой доступ к видео памяти .
Для создания меню, которые действительно "исчезают" вы должны миновать вызовы функций BIOS и прямо обращаться к видеопамяти. Это позволяет высвечивать символы с молниеносной быстротой. При прямой записи и чтении из видеопамяти вы можете использовать исчезающие меню в реальном времени!
Чтение и запись в видео память требует использования дальних указателей для Турбо-Си или предопределенных массивов для Тур- бо-Паскаля.
3.9. Определение расположения видео памяти.
Одноцветный адаптер использует для видео памяти адрес В000:0000Н, а все остальные - В800:0000Н. Для того, чтобы программы с меню работали правильно с каждым адаптером, они должны знать, какой адаптер имеет система. К счастью, для этого существует простой способ. Прерывание BIOS 16, функция 15 возвращает текущий видео режим.
Как только переменной uk присвоен соответствующий адрес, проявляется простой способ использовать ее для чтения и записи символов в видео память. Запомните, видео память требует двух байтов для каждого символа, один для символа, а другой для атрибута. Из-за того, что символьный байт первый, а атрибутный - второй, то каждой строке экрана требуется 160 байт. Для того, чтобы определить адрес отдельного символа вы должны использовать формулу:
44
адрес=адрес_адаптера+Х*160+Y*2
Для эффективного использования видеопамяти при выборе пользователя достаточно в текущей позиции ( которая в данный момент времени выводится с негативными атрибутами ) изменить атрибуты, не переписывая по новому коды символов, а в следующей выбранной позиции установить негативные атрибуты.
4.Порядок выполнения работы.
4.1.Написать программу создания всплывающего окна, которое содержит анкетные данные студента и исчезает после нажатия любой клавиши.
Программа должна использовать прямой доступ к видеопамяти и выполнять следующие действия:
-определяют начальный адрес свободного пространства ОЗУ для копирования части экрана,где будет размещено окно.
-сохраняет часть экрана. -высвечивает окно.
-восстанавливает экран при нажатии любой клавиши.
4.2.Написать программу создания исчезающего меню,характеристики которого соответствуют индивидуальному заданию.Программа должна использовать прямой доступ к видеопамяти и выполнять следующие действия:
-определяет начальный адрес свободного пространства ОЗУ для копирования части экрана,где будет размещено меню. (В случае отсутствия достаточного адресного пространства печать сообщения об ошибке ).
-сохраняет часть экрана.
-высвечивает меню с подсвеченной первой позицией в негативе. -обеспечивает изменение подсветки пунктов меню при нажатии
пользователем клавиш управления СТРЕЛКА ВНИЗ и СТРЕЛКА ВВЕРХ для вертикальных меню и СТРЕЛКА ВЛЕВО и СТРЕЛКА ВПРАВО для горизонтальных меню.
-обеспечивает сохранение номера позиции меню в переменной n_pos.
-обеспечивает выход на клавише ENTER (возвращает n_pos ) и по клавише ESC ( возвращает -1)
-восстанавливает экран после выхода из меню.
5.Особенности программирования .
5.1.На языке Турбо-Паскаль.
5.1.1. Буфер видеоконтроллера в текстовом режиме можно предс45
тавить в виде массива:
buff:array[0..3999] of byte absolute $B800:$0000.
Тогда для обращения (записи или считыванию) к символу, расположенному на экране в i-й строке и в j-м столбце необходимо по адресу buff[i*160+j*2] записать или прочитать ASCII код символа, а по следующему - байт видеоатрибута.
5.1.2. Если слова заданы в виде строки символов s:string,
то для определения ASCII кода k-й буквы строки можно воспользоваться выражением ord(s[k]).
5.1.3. Для выделения области в памяти требуемого размера (и определения ее начального адреса) используется процедура GetMem:
GetMem(p,size),
где p - указатель любого типа (p:pointer); size - выражение типа word.
При выполнении этой процедуры выделяется область памяти на которую указывает p, размер которой в байтах задается выражением size. Тогда для записи i-го байта (начиная с 0-го) в выделенную область памяти используем выражение:
byte(Ptr(Seg(p^),Ofs(p^)+i)^):=b,
где функции Seg(p^) и Ofs(p^) определяют значения сегмента и смещения начала выделенной области;
функция Ptr преобразует адрес, заданный в виде пары сегмент и смещение в значение типа указатель.
Кроме того, для придания выражению Ptr(Seg(p^),Ofs(p^)+i)^ типа byte (поскольку справа от знака присваивания стоит выражение этого типа) было применено преобразование типов.
Для чтения j -го байта из выделенной области используется аналогичное выражение:
b:=byte(Ptr(Seg(p^),Ofs(p^)+j)^).
5.2. На языке Турбо-Си.
5.2.1. Для непосредственной адресации к видеопамяти используются дальние указатели,которые описываются как
char far *uk,*v;
и устанавливаются на начало видеопамяти оператором
uk=(char far *)0xB8000000;
с учетом особенностей адресации видеопамяти установка указателя на символ в позиции экрана с координатами x,y выполняется следующим образом.
46
v=uk;
v+=(160*y)+2*x;
По следующему адресу хранится атрибут.
5.2.2. Для определения начального адреса свободного пространства ОЗУ заданного объема используется функция malloc,(требует подключения библиотеки alloc.h ) которая возвращает начальный адрес свободного ОЗУ при достаточном объеме или 0 в противном случае. Фрагмент использования функции приводится ниже:
#include<alloc.h> char far *p
p=( char far *) malloc(2*N_str*len); if(!p){printf(" нет памяти под меню \n");getch();
exit(1);
где:N_str -число позиций len-длина каждой позиции
5.2.3.Задание массива имен позиций можно удобно представить в виде:
char *text_p[]={"позиция 1","позиция 2",...};
тогда установка указателя на начало i-й строки выполняется оператором
*p=*text_p[i];
5.2.4. Анализ нажатой клавиши при выборе пользователем пункта меню можно реализовать следующим фрагментом программы:
for(; ; )
{
if ((c=getch())==0)c=getch(); switch(c)
{case 13:return n_pos; case 27:return -1;
case 80:---------------- break;
case 72:---------------- |
break; |
}
}
47
6.Индивидуальные задания
6.1.По первой цифре номера студента выбрать тип меню: 0-вертикальное;1-горизонтальное;
6.2.В таблице 1 по второй цифре номера студента выбрать остальные параметры меню согласно таблице.
Таблица 1 ╔══════════════════╦═══════════════════════════════════════╗
║ |
Параметры ║ |
Номер в журнале |
║ |
║ |
║ 0 1 2 3 4 5 6 7 8 9 ║ |
║══════════════════╬═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╣
║ |
X |
║ 45│ 0 |
│10 │ |
20│ |
40│ |
15│ |
30│ 5 |
│ |
25│ |
35║ |
||||||
║ |
Y |
║ 10│ 1 |
│ 3 |
│ |
10│ |
5 |
│ |
8 |
│ |
7 |
│ 15│ |
0 |
│ |
12║ |
||
║ |
N_str |
║ 8 │ 5 |
│ 6 |
│ |
8 |
│ |
7 |
│ |
9 |
│ |
10│ 4 |
│ |
15│ |
7║ |
||
║ |
len |
║ 10│ 10│ 11│ |
9 |
│ |
8 |
│ |
15│ |
8 |
│ 20│ |
9 |
│ |
16║ |
||||
║ |
N_str1 |
║ 7 │ 4 |
│ 5 |
│ |
6 |
│ |
7 |
│ |
8 |
│ |
9 |
│ 8 |
│ |
6 |
│ |
5 ║ |
║ |
len1 |
║ 11│ 20│ 16│12 │11 |
│10 │ |
8 |
│ 10│12 │ |
16║ |
╚══════════════════╩═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝
где: x,y-координаты верхнего левого угла;
(для горизонтального меню x=0 для всех вариантов) N_str-число позиций вертикального меню;
lenдлина строки вертикального меню; N_str1число позиций горизонтального меню;
len1длина каждой позиции горизонтального меню.
7. Содержание отчета
7.1.Тема лабораторной работы. 7.2.Цель работы.
7.3.Порядок выполнения. 7.4.Индивидуальное задание. 7.5.Текст программы. 7.6.Результаты работы программы. 7.7.Выводы.
Лабораторная работа 15
РАБОТА В ГРАФИЧЕСКОМ РЕЖИМЕ. УПРАВЛЕНИЕ ЭКРАНОМ,ЦВЕТОМ. ИЗОБРАЖЕНИЕ ТОЧКИ
1. Цель работы
Приобретение практических навыков работы с видеомонитором в графическом режиме.
48
2. Темы для предварительной проработки
2.1.Назначение и режимы работы адаптера в графическом режиме.
2.2.Организация видеобуфера в графическом режиме.
3. Описание работы
Цветной графический адаптер имеет три графических режима, PCjr - шесть, а EGA - семь. Требования к размеру памяти существенно различаются для доступных режимов в зависимости от разрешения экрана и числа цветов. В своих улучшенных графических режимах EGA использует память дисплея совсем по-другому, чем остальные видеосистемы, но он точно эмулирует их методы работы с памятью в трех общих режимах.
3.1. Цветной графический адаптер CGA и система PCjr.
Сначала рассмотрим цветной адаптер и систему PCjr. Два цвета (черный и белый) требуют только один бит памяти для каждой точки на экране. Четыре цвета занимают 2 бита, а 16 цветов - 4 (8-цвет- ные режимы не используются, поскольку три бита, требующиеся для их представления, нельзя удобно разместить в битах байта). Для всех режимов по вертикали имеется 200 точек. Низкое разрешение (используемое только на PCjr) выводит 160 точек по горизонтали, среднее разрешение - вдвое больше (320 точек), а высокое разрешение - еще вдвое больше (640 точек).
Вдвух- и четырехцветном режимах PCjr имеет возможность выбрать любой из 16 доступных цветов. Цветной адаптер более ограничен. В двухцветном режиме он всегда ограничен белым и черным, а в четырехцветном режиме только цвет фона может выбираться из 16 цветов, в то время как основной цвет нужно брать только из двух предопределенных палитр. Палитра 0 содержит коричневый, зеленый и красный цвета, а палитра 1 - циан, магента и белый.
Вотличие от текстовых данных в режимах 4-6 и 8-А графические данные разбиты на видеостранице на части. В большинстве режимов данные разбиваются на две части, при этом первая половина буфера содержит данные для четных строк экрана, а вторая - для нечетных (строки нумеруются начиная с верха экрана вниз). Однако в 16-цвет- ных режимах PCjr буфер размером 32К делится на четыре части, каждая из которых содержит данные для каждой четвертой строки.
В4-цветных режимах первый байт буфера содержит информацию о самых левых точках строки 0, причем старший бит относится к самой левой точке. Второй байт содержит информацию о следующем сегменте строки и т.д. Для всей строки требуется 80 байт. 81-й байт содержит информацию о левом конце строки 2. В 16-цветных режимах карти-
на приблизительно такая же, но для каждой строки требуется 160
49
байт и каждая часть буфера содержит данные только для вдвое меньшего числа строк. Для цветного графического адаптера четные строки занимают память со смещениями от 0000 до 1F3FH, а нечетные - от 2000H до 3F3FH. Промежуток между 1F3FH и 2000Н игнорируется.
Для цветного графического адаптера цвет доступен только в режиме умеренного разрешения. Для каждой точки отводятся два бита каждого байта видеобуфера. Четыре возможные комбинации этих битов представляют один фоновый и три основных цвета. Фоновый цвет может быть любым из 16. Однако три основных цвета могут выбираться из одной из двух палитр, каждая из которых содержит только три предопределенных цвета:
Номер кода |
Цепочка битов |
Палитра 0 |
Палитра 1 |
0 |
00 |
цвет фона |
цвет фона |
1 |
01 |
зеленый |
циан |
2 |
10 |
красный |
магента |
3 |
11 |
желтый/коричневый |
белый |
Если вы в какой-то момент переключились между палитрами, то все выведенные на экран цвета будут соответственно изменены.
Отметим, что BIOS хранит в своей области данных однобайтовую переменную, которая содержит текущий номер палитры. Ее адрес - 0040:0066Н. Изменение этого числа не меняет текущую установку палитры; наоборот, если вы измените цвет палитры другими средствами, помимо функций операционной системы, то значение этой переменной будет модифицировано.
Для цветного адаптера мы можем получить доступ к "регистру выбора цвета" через порт 3D9H. В графических режимах этот регистр действует по-другому, чем в текстовых. Биты 0-3 содержат информацию о фоновом цвете в обычном формате (соответственно синий, зеленый и красный компоненты и интенсивность). Бит 5 выбирает палитру, и когда этот бит равен 0, то назначается палитра номер 0. В графических режимах остальные биты не имеют значения. Этот регистр только для записи, поэтому вы должны указывать информацию и о фоновом цвете, и о палитре при изменении любого из них.
3.2.Расширенный графический адаптер.
Расширенный Графический Адаптер (Enhanced Graphics Adapter - EGA) фирмы IBM представляет собой графический контроллер, обеспечивающий возможность работы в различных видеорежимах совместно с цветными или монохромными мониторами с цифровыми входами.
50