15.4.7. Опрос клавиатуры
15.4.7.1. Функция KeyPressed. Эта функция возвращает логическое значение True, если в буфере ввода с клавиатуры имеется хотя бы один символ, и False, если буфер пуст.
Когда программа стартует, буфер обычно пуст. Но любое нажатие клавиши (кроме клавиши регистров Ctrl, Shift, Alt и переключателей типа NumLock, CapsLock и т.п.) занесет ее код в буфер. Коды в буфере будут храниться до тех пор, пока они либо не будут считаны, либо буфер не будет очищен самой программой.
Очищают буфер полностью процедуры Read и ReadLn, а также операция Reset над файлом, связанным с консолью. Вообще говоря, процедуры Read и ReadLn получают ввод с клавиатуры через еще один специальный буфер. (Этим, кстати, и объясняется ограничение в 126 символов для одной вводимой строки — такова емкость буфера строки.)
Имеется еще одна функция, очищающая буфер клавиатуры — ReadKey. Но в отличие от Read и ReadLn, которые очищают весь буфер после своей работы, ReadKey как бы «вынимает» последовательно введенные в него символы по одному за каждое обращение.
Мы неспроста дали такое подробное описание механизма работы буфера ввода с клавиатуры. Ведь самое естественное место логической функции KeyPressed — в опросе состояния клавиатуры:
if KeyPressed then Действие ;
и очень заманчиво использовать ее как флаг факта нажатия клавиши. Но такая трактовка не всегда корректна. Функция KeyPressed является флагом не только сиюминутного нажатия, но и нажатий вообще во время работы программы. Так, если пользователь заденет несколько клавиш во время «молчаливого» счета своей задачи, то внешне ничего не произойдет. Но буфер запомнит все, что было «введено», и функция KeyPressed совершенно резонно не захочет работать так, как от нее ожидалось бы.
- 343 -
Чтобы узнать, как очистить буфер перед опросом и как опрашиватъ клавиатуру в реальном времени, мы должны рассмотреть вторую функцию работы с клавиатурой.
15.4.7.2. Функция опроса ReadKey. Пользователь может считать, что эта функция опрашивает клавиатуру, но программист обязан знать, что на самом деле эта функция опрашивает буфер ввода с клавиатуры со всеми рассмотренными выше последствиями и особенностями.
Функция возвращает всегда один символ, т.е. одно значение типа Char. Есть две важные особенности:
1) полученные функцией символы никогда не отражаются на дисплее, т.е. ввод символа происходит вслепую;
2) режим работы ReadKey зависит от состояния буфера ввода: содержит ли он символы или пуст. Если в буфере что-то есть, то ReadKey вернет первый символ в буфере (тот, который был введен раньше остальных) и удалит этот символ из буфера. Но если буфер пуст, то функция ReadKey приостанавливает работу программы и ждет, пока не будет нажата какая-либо клавиша, генерирующая символьный код.
Используя эти особенности, можно построить несколько довольно полезных конструкций, что мы и сделаем в качестве иллюстрации (переменная Ch должна быть типа Char):
while KeyPressed do ch:=ReadKey; { очистка буфера ввода }
repeat until KeyPressed; { ожидание нажатия любой клавиши }
Последний цикл завершится, когда в буфер попадет какой-либо символ. Программа должна в конце очистить буфер, иначе все, что накопилось в буфере, вывалится в строку MS-DOS или в редактор среды программирования.
Тех, кто не нашел ответы на свои вопросы в этом разделе, мы просим обратиться к гл. 21 «Как осуществить полный доступ к клавиатуре», где рассмотрены примеры разделения функциональных и символьных кодов, опрос регистров и многое другое.