Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Системные функции ввода с клавиатуры

В операционной системе Windows ввод символов даже для консоли организован довольно сложно. Эта организация ввода символов была предварительно рассмотрена в предыдущем разделе. Теперь рассмотрим более детально строение экземпляров структуры типа KEY_EVENT_RECORD. Именно эти структуры данных оказываются в сообщении типа INPUT_RECORD, когда ключевое поле EventType в ней имеет значение KEY_EVENT.

Структура данных KEY_EVENT_RECORD для записи ввода с клавиатуры описана в заголовочном файле как

typedef struct _KEY_EVENT_RECORD {

BOOL bKeyDown;

WORD wRepeatCount;

WORD wVirtualKeyCode;

WORD wVirtualScanCode;

union {

WCHAR UnicodeChar;

CHAR AsciiChar;

} uChar;

DWORD dwControlKeyState;

} KEY_EVENT_RECORD, *PKEY_EVENT_RECORD;

В ней содержатся поля как собственно ASCII-кода символа (который обычно и нужен при вводе с клавиатуры), так и дополнительная информация. Поле bKeyDown определяет, нажата клавиша (значения TRUE) или отпущена (значение FALSE). Заметим, что для каждого события нажатия или отпускания клавиши формируется свое отдельное сообщение. Поле wRepeatCount дает число многократных сигналов от клавиши, формируемых в автоматическом режиме при длительном удержании клавиши (для последовательности таких событий ОС формирует только одно сообщение – для экономии). Поле wVirtualScanCode дает скан-код нажатой клавиши, а поле wVirtualKeyCode определяет специальный код для управляющих клавиш, принятый в системах Windows. Наконец, поле dwControlKeyState комбинацией бит информирует получателя сообщения о текущем – на момент формирования сообщения - состоянии нажатий на специальные клавиши. Коды клавиш для этого поля описаны следующими определениями

// ControlKeyState flags

#define RIGHT_ALT_PRESSED 0x0001 // the right alt key is pressed.

#define LEFT_ALT_PRESSED 0x0002 // the left alt key is pressed.

#define RIGHT_CTRL_PRESSED 0x0004 // the right ctrl key is pressed.

#define LEFT_CTRL_PRESSED 0x0008 // the left ctrl key is pressed.

#define SHIFT_PRESSED 0x0010 // the shift key is pressed.

#define NUMLOCK_ON 0x0020 // the numlock light is on.

#define SCROLLLOCK_ON 0x0040 // the scrolllock light is on.

#define CAPSLOCK_ON 0x0080 // the capslock light is on.

#define ENHANCED_KEY 0x0100 // the key is enhanced.

В операционной системе Unix нет специальных средств, отличных от стандарта языка Си, для ввода символов с консоли, а предполагается использовать стандартные библиотеки языка Си. Поэтому для ввода с консоли следует использовать стандартные функции getchar и getch.

Дополнительные возможности в Windows предоставляются путем выборочного задания типов событий, которые будут далее поступать при вызове функции ReadConsoleInput. Этот выбор задается функцией SetConsoleMode с прототипом

BOOL SetConsoleMode(HANDLE hConsHandle, DWORD mode).

Параметр mode задает в ней новый режим управления вводом (или выводом, если в качестве первого параметра hConsHandle задан хэндл буфера консольного вывода). Возможные режимы для буфера ввода с консоли задаются константами

#define ENABLE_PROCESSED_INPUT 0x0001

#define ENABLE_LINE_INPUT 0x0002

#define ENABLE_ECHO_INPUT 0x0004

#define ENABLE_WINDOW_INPUT 0x0008

#define ENABLE_MOUSE_INPUT 0x0010

Если с помощью функции SetConsoleMode задать в качестве режима значение константы ENABLE_MOUSE_INPUT, а другие константы при этом задании режима не использовать, то по запросу событий будут поступать только сообщения от мыши (даже если пользователь и пытается нажимать на клавиши клавиатуры при активном окне текущего приложения). Если же с помощью данной функции установить только режим ENABLE_PROCESSED_INPUT, то будут поступать сообщения лишь от клавиатуры и т.п.

Отключив режим ENABLE_ECHO_INPUT, можно отказаться от исполь­зо­ва­ния эха символов, но делать это следует временно – с последующим вос­станов­лением стандартного режима. Поэтому вначале целесообразно запомнить предыдущее значение режима для буфера ввода консоли, для этого действия предназначена функция

BOOL GetConsoleMode(HANDLE hConsHandle, DWORD* pmode),

в которой возвращаемое значение текущего режима передается через второй параметр ее вызова.

Как уже пояснялось выше, в Unix для доступа непосредственно к клавиатуре следует выполнить открытие специализированного виртуального устройства /dev/tty. В общем случае универсальная функция read() в варианте использования, читающем по одному символу, может обеспечить посимвольный ввод. Но при этом для программиста возникает проблема, обусловленная тем, что вводимые символы поступают в программу только после нажатия на клавишу Enter, когда используется обычный (стандартный) режим работы консоли. (Информация о нажатии клавиш клавиатуры оказывается недоступной программе до воздействия на клавишу Enter.)

В тех ситуациях, когда программе Unix необходим полноценный посимвольный ввод, следует отменить стандартный режим работы консоли. Для этих целей используются функции с прототипами

int tcgetattr(int htty, struct termios *tsave),

int tcsetattr(int htty, int action, struct termios *tnew),

где параметр htty задает хэндл консоли.

Функция tcgetattr() позволяет получить детальную информацию о текущих режимах консоли, а функция tcsetattr() – установить новые режимы. Получение текущих режимов перед установкой новых настоятельно рекомендуется для восстановления стандартных режимов работы консоли перед выходом из программы (иначе нестандартный режим может существенно нарушить работу последующих программ на данной консоли). Обе функции требуют использования заголовочного файла с именем termios.h. Среди возможных значений параметра action функции tcsetattr() чаще всего используется задаваемое символической константой TCSAFLUSH (параметр задает, когда и как будут проведены изменения режима консоли).

Структура типа termios содержит множество полей, подробную информацию о которых можно получить в технической документации. С целью настройки режима для одиночного ввода символов с клавиатуры – требуется изменить поля с именами c_lflag и c_cc. Второе из них представляет собой массив, в элементах которого с индексами, задаваемыми константами VMIN и VTIME, следует установить значения 1 и 0 соответственно. В поле c_lflag следует сбросить стандартный режим (обозначаемый константой ICANON) и, как правило, режим автоматического отображения символа (обозначаемый константой ECHO). При этом не следует изменять значения битов, кодирующих другие разновидности режимов. Поэтому последовательность команд, решающая рассматриваемую задачу, имеет вид

struct termios sterm, term;

int htty;

...

htty=open("/dev/tty", O_RDON LY);

if (htty = = -1) {... exit(1);}

tcgetattr(htty,&sterm);

tcgetattr(htty,&term);

term.c_lflag &= ~(ICANON | ECHO);

term.c_cc[VMIN]=1;

term.c_cc[VTIME]=0;

tcsetattr(htty,TCSAFLUSH, &term);

... // использование режима одиночного ввода символов

... // оператором read(htty, имяодносимвольногомассива, 1);

tcsetattr(htty,TCSAFLUSH, &sterm);

В простейшем случае вместо хэндла htty виртуального терминала можно использовать хэндл стандартного ввода со значением 0, но только в том случае, когда есть уверенность, что он соответствует именно консоли. (В Unix имеется функция int isatty(int htty), которая позволяет определить, соответствует ли терминалу заданный ее аргументом хэндл, что сообщается возвращаемым значением, отличным от нуля.)

Особо следует остановиться на кодировании управляющих клавиш в терминалах Unix. Если в других рассматривавшихся операционных системах для распознавания таких клавиш предназначен специальный скан-код, то в Unix используются управляющие последовательности кодирования! Управляющие последовательности и для кодирования управляющих клавиш имеют в качестве первых двух символов коды ‘\033’ и ‘[‘. Следующие символы таких последовательностей позволяют различать конкретную управляющую клавишу.

Как правило, клавиши управляющих стрелок имеют трехсимвольные кодирующие последовательности esc [A (задает стрелку вверх), esc [B (стрелка вниз), esc [D (стрелка влево) и esc [C (стрелка вправо). Управляющие клавиши от F1 до F5 выдают соответственно четырехсимвольные управляющие последовательности esc [[A, esc [[B, esc [[C, esc [[D, esc [[E. Управляющие клавиши от F6 до F10 выдают управляющие последовательности esc [17~, esc [18~, esc [19~, esc [20~, esc [21~, которые состоят из пяти составляющих символов. Управляющие клавиши F11 и F12 выдают аналогичные управляющие последовательности esc [23~, esc [24~, а клавиши Home, Insert, Delete и End выдают управляющие последовательности esc [1~, esc [2~, esc [3~ и esc [4~. (В этих обозначениях буквосочетание esc представляет единственный символ с внутренним кодом 27 и записывается в тексте для языка Си как \033.)

Следует заметить, что конкретное кодирование этих последовательностей может зависеть от настройки рабочей версии ОС или от ее текущей модификации. До последнего времени управление терминалами в Unix являлось областью, известной своей несовместимостью между отдельными версиями (клонами) этой операционной системы. К настоящему времени принят стандарт XSI, обеспечивающий стандартный набор системных вызовов для управления терминалами. Использование этого стандарта обеспечивает совместимость между конкретными версиями Unix, которые его поддерживают.

<== предыдущая лекция | следующая лекция ==>
Событийно-управляемый ввод | Опрос ввода с клавиатуры в программе
Поделиться с друзьями:


Дата добавления: 2014-01-05; Просмотров: 484; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.015 сек.