Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
9
Добавлен:
13.02.2016
Размер:
158.49 Кб
Скачать

СОЗДАНИЕ «ВСПЛЫВАЮЩИХ» МЕНЮ

При создании меню будем придерживаться следующей последовательности:

1.Сохранить область экрана под меню;

2.Высветить рамку вокруг меню, если надо;

3.Высветить меню;

4.Получить ответ пользователя;

5.Восстановить экран в исходное состояние.

Функции, создающей исчезающее меню, должна быть передана некоторая информация:

1.Во-первых, это список предоставляемых меню режимов, т.е. число режимов(пунктов в меню) и названия этих пунктов;

2.Список «горячих» клавиш. (Передаем строку, которая содержит символы "горячих" клавиш в том же порядке, что и строки меню);

3.Функция должна также знать, где расположить меню, то есть нужны координаты X и Y;

4.В некоторых ситуациях может быть желательным помещать меню в рамку, а в других - нет. Поэтому должно быть передано значение рамка включена/выключена.

Управление:

Пользователь может вводить выбор одним из двух способов. Во-первых с помощью клавиш СТРЕЛКА ВНИЗ и СТРЕЛКА ВВЕРХ может переместить освещение на строку и нажать Ввод для ее выбора, (Обычно освещение строки выполняется в инверсном режиме.) Освещенную строку также можно передвигать «пробелом».

Каждый раз при нажатии стрелки освещенная опция переходит в нормальное изображение, а следующая - освещается. Нажатие стрелки вниз (или «пробел»), в момент освещения крайней нижней позиции, означает возвращение к первому значению. То же самое, но наоборот происходит когда нажимается стрелка вверх при освещенной первой позиции.

Второй способ это нажатие клавиши, связанной с выбором (нажатие «горячей» клавиши).

Выход из меню: нажатие клавиши ESC.

При опросе клавиатуры мы должны использовать bioskey() вместо getchar(). Проблема заключается в том, что программа должна иметь возможность считывать полный 16 битный скан код, генерируемый нажатием клавиши. Если нажата символьная клавиша, то символ помещается в младшие 8 бит, а старшие 8 бит равны 0. Однако, если нажата специальная клавиша, такая, как стрелка, младший байт равен 0, а старший содержит код позиции клавиши. Коды позиции для стрелки вверх и стрелки вниз равны 72 и 80 соответственно. Такие функции, как getchar(), возвращают только код символа, а необходимо анализировать полный 16-битный скан код. Используя bioskey() мы можем анализировать нажатия F1, F2, …, SHIFT, CapsLock и т.д.

bioskey Интерфейс клавиатуры, напрямую использующий операции BIOS

Синтаксис #include <bios.h> int bioskey(int cmd);

-----------------------------------------------------------------

¦=================================================================-

Это - интерфейс прикладного уровня с клавиатурой. Нажатия клавиш на самом деле обрабатываются асинхронно на заднем плане. Когда клавиша получена от клавиатуры, она обрабатывается прерыванием INT 09H и помещается в циклическую очередь (буфер клавиатуры).

INT 16H: Сервис клавиатуры (int cmd в bioskey)

-----------------------------------------------------------------

00H читать (ожидать) следующую нажатую клавишу

Выход: AL = ASCII символ (если AL=0, AH содержит Расширенный код

ASCII )

AH = Сканкод или Расширенный код ASCII

------------------------------------------------------------------

01H Проверить готовность символа (и показать его, если так) Выход: ZF = 1 если символ не готов.

ZF = 0 если символ готов.

AX = как для подфункции 00H (но символ здесь не удаляется из очереди).

------------------------------------------------------------------

02H Читать состояние shift-клавиш. Определить, какие shift-клавиши нажаты в данный момент, находится ли клавиатура в состоянии NumLock, и т.п.

Выход: AL = статус клавиатуры

------------------------------------------------------------------

clskbr(); for(;;) {

while(!bioskey(1)); /* ждать нажатия */ c.i=bioskey(0); // взять код из буфера клавиатуры

if(c.ch[0]) { /* обычная клавиша */ switch(c.ch[0]) {

case '\r' : return arrow_choice;

case ' ' : arrow_choice++; break; /* "пробел" - на пункт ниже */ case 27 : return -1; /* выйти из меню */

}

}

else { /* специальная клавиша */ switch(c.ch[1]) {

case 72 : arrow_choice--; break;/* стрелка вниз */ case 80 : arrow_choice++; break;/* стрелка вверх */

}

}

Возможные модификации (улучшения):

1.Добавить подсказку под меню (необходимо проверять возможность вывода )

2.Добавить вывод рамок в цвете;

3.Добавить выбор типа линии для рамки;

4.Добавить «раскраску» горячих клавиш;

5.Очистка места (под меню)

6.Переход на прямой доступ к видеопамяти – ускорит вывод данных.

bioskey Интерфейс клавиатуры, напрямую использующий

операции BIOS

-----------------------------------------------------------------

Синтаксис

#include <bios.h>

 

 

 

 

 

int bioskey(int cmd);

 

 

 

Замечания

Эта функция

выполняет

различные

операции

с

 

клавиатурой, используя при этом прерывание BIOS

 

0х16. Параметр cmd определяет выполняемую опе-

 

рацию.

 

 

 

 

 

Возвращаемое

Значение, возвращаемое

функцией,

зависит

от

значение

выполняемой

ею

операции, которая, в свою

очередь, определяется значением параметра cmd:

0 Если младшие 8 бит отличны от нуля, bioskey возвращает символ в коде ASCII, представляющий следующую нажатую клавишу клавиатуры (или ожидающую из буфера клавиатуры). Если же младшие 8 бит нулевые, то в старших 8 битах передаются расширенные коды клавиатуры, приведенные в Техническом справочном руководстве по IBM PC.

1 Производит проверку

наличия

символа

для

чтения

(нажата ли клавиша).

Если возвращае-

мое значение равно 0, считывать нечего. Если

нажата

комбинация

клавиш <Ctrl/Break>,

то

возвращаемое значение равно 0xFFFFF (-1).

В

противном случае возвращается значение сле-

дующей

нажатой клавиши. Сам же код нажатой

клавиши сохраняется для возвращения при сле-

дующем

вызове bioskey со значением cmd, рав-

ном 0.

 

 

 

 

2 Запрашивает текущий статус функциональных клавиш (типа <Shift>). Возвращаемое значение получается при логическом сложении следующих значений (операция OR):

бит 7

0x80

включен режим

Insert

(вставка)

бит 6

0x40

включен режим

Caps

 

бит 5

0x20

включен режим

Num Lock

бит 4

0x10

включен режим

Scroll

Lock

бит 3

0x08

нажата клавиша Alt

 

бит 2

0x04

нажата клавиша Ctrl

Shift

бит 1

0x02

нажата левая клавиша

бит 0

0x01

нажата правая

клавиша Shift

Пример

#include <stdio.h> #include <bios.h> #include <ctype.h>

#define RIGHT

0x01

#define LEFT

0x02

#define

CTRL

0x04

#define

ALT

0x08

int main (void)

{

int key, modifiers;

/* пока не будет нажата клавиша функция 1 возвращает 0 */ while(bioskey(1) == 0);

/* функция 0 используется для получения значения нажатой клавиши*/

key = bioskey(0);

/* функция 2 используется для определения того, была ли нажата функциональная клавиша типа <Sсhift> */

modifiers = bioskey (2);

if (modifiers)

 

{

 

printf ("[");

printf("RIGHT");

if (modifiers & RIGHT)

if (modifiers & LEFT)

printf("LEFT");

if (modifiers & CTRL)

printf("CTRL");

if (modifiers & ALT )

printf("ALT");

printf ("]");

 

}

 

/* вывести прочитанный символ */ if (isalnum(key & 0xFF))

printf("'%c'\n", key); else

printf("%#02x\n", key);

return 0;

}