Оператор
Оператор ON KEY
Реакцию на нажатие клавиши можно не проверять в каждом цикле, а вынести в отдельную процедуру. Оператор ON KEY назначает такую процедуру SUB обработчиком нажатия, и среда вызывает её между инструкциями программы, когда в очереди есть подходящее событие. Параметр обработчика передаётся по значению; BYREF не допускается.
Когда обработчик удобнее опроса
Обработчик подходит для отдельного действия по клавише: программа продолжает основную работу, а реакция выполняется в назначенной процедуре. Можно назначить обработчик конкретного имени или запасной обработчик "ANY". Для непрерывной проверки удержания используется KEYDOWN.
Оператор использует доступную клавиатурную очередь. Без окна SCREEN события приходят из текстовой области IDE; после открытия текстового или графического экрана — из его окна. Обработчик и опрос читают одну очередь: перехваченное событие уже не попадёт в INKEY.
Синтаксис
ON KEY(<клавиша>), <имя обработчика>
ON KEY(<клавиша>), ON
ON KEY(<клавиша>), STOP
ON KEY(<клавиша>), OFF
Объявите обработчик как SUB без параметров либо с одним параметром типа STRING:
SUB <имя обработчика>()
END SUB
SUB <имя обработчика>(<имя клавиши> AS STRING)
END SUB
Аргументы и состояния
В записи синтаксиса keyText обозначает строковое имя, а HandlerName — имя объявленной процедуры, например HandleLeft. Слова ON, STOP и OFF после запятой управляют состоянием обработчика.
keyText— строковое выражение с именем клавиши, например"LEFT","ESCAPE"или"A". Канонические имена и алиасы перечислены в общей таблице имён клавиш. Специальная строка"ANY"задаёт обработчик любой клавиши.HandlerName— видимая в текущем месте процедураSUBбез параметров или с одним параметромSTRING.ON— возобновление ранее зарегистрированного обработчика.STOP— пауза ранее зарегистрированного обработчика без удаления регистрации.OFF— полное отключение обработчика для той же клавиши.
Аргумент клавиши должен иметь тип STRING. Пустая строка и строка из пробелов не создают регистрацию. Повторная регистрация для той же нормализованной цели заменяет прежнюю процедуру. ON и STOP для ещё не зарегистрированной цели не вызывают ошибку и не назначают процедуру.
Порядок обработки клавиш
- Обработчик вызывается между операторами, а не посреди вычисления выражения.
- Совпавшая клавиша считается обработанной и не попадает в последующий
INKEY. - Если клавиша не подошла ни под один зарегистрированный обработчик, она остаётся в очереди и может быть прочитана через
INKEY. - Повторная регистрация для той же клавиши заменяет предыдущий обработчик.
- Каноническое имя и алиас считаются одной клавишей: например,
ON KEY("ESCAPE"), HandleEscсработает на событие"ESC". ON KEY("ANY"), HandlerNameвызывается для доступных клавиш, у которых нет более точного обработчика.- Если для клавиши есть точный обработчик и одновременно зарегистрирован
"ANY", сначала применяется точный обработчик. - Во время выполнения обработчика повторный вход в другой клавиатурный обработчик не делается.
STOPдействует на события, которые приходят после паузы. Уже накопленная клавиша может быть обработана на ближайшей границе оператора до того, как программа выполнит строкуON KEY(...), STOP.- Если обработчик объявлен с одним параметром
STRING, в него передаётся нормализованное имя фактической клавиши. ДляON KEY("ANY")это не строка"ANY", а имя сработавшей клавиши, например"LEFT"или"ESC". - Состояния удерживаемых клавиш учитываются в сочетаниях. Сам оператор
ON KEYреагирует на события клавиатуры; для мыши используетсяON MOUSE.
При подходящем событии сначала выбирается включённый обработчик сочетания с удерживаемыми предыдущими клавишами; сочетание с большим числом требуемых клавиш имеет приоритет. Затем проверяются одиночная клавиша и ANY. Поэтому обработчик CTRL+LEFT может получить событие раньше обработчика LEFT.
Обработчик любой клавиши
ON KEY("ANY"), HandleAny
FOR i = 1 TO 200000
NEXT
ON KEY("ANY"), OFF
SUB HandleAny()
PRINT "any key"
END SUB
Имя клавиши в обработчике
ON KEY("ANY"), HandleKey
FOR i = 1 TO 200000
NEXT
ON KEY("ANY"), OFF
SUB HandleKey(keyName AS STRING)
PRINT keyName
END SUB
Аккорд клавиш
Для сочетания разделите имена знаком +. Последняя клавиша должна прийти событием, а предыдущие — удерживаться. Например, ON KEY("CTRL+LEFT"), Handler реагирует на нажатие LEFT при удерживаемом CTRL; так же проверяется сочетание в KEYPRESS.
ON KEY("CTRL+LEFT"), HandleChord
FOR i = 1 TO 200000
NEXT
ON KEY("CTRL+LEFT"), OFF
SUB HandleChord(keyName AS STRING)
PRINT keyName
END SUB
Если у процедуры есть строковый параметр, при срабатывании сочетания он получает его каноническую запись, например "CTRL+LEFT".
Отключение обработчика
ON KEY("ESC"), HandleEsc
' ...
ON KEY("ESC"), OFF
SUB HandleEsc()
PRINT "ESC"
END SUB
Пауза и возобновление
Режим STOP приостанавливает вызовы, сохраняя регистрацию процедуры; режим ON возобновляет их. Пока обработчик на паузе, клавиша остаётся обычным событием для INKEY() или KEYPRESS().
ON KEY("LEFT"), HandleLeft
ON KEY("LEFT"), STOP
' Нажатие LEFT не вызовет HandleLeft,
' но останется обычной клавишей для INKEY() или KEYPRESS().
ON KEY("LEFT"), ON
' Следующее нажатие LEFT снова вызовет HandleLeft.
SUB HandleLeft()
PRINT "LEFT"
END SUB
Диагностика
MB2034: в обработчик оператораON KEYпередана не процедураSUBбез параметров или с одним параметромSTRING.
Пример обработчика клавиши
ON KEY("LEFT"), HandleLeft
FOR i = 1 TO 200000
NEXT
ON KEY("LEFT"), OFF
SUB HandleLeft()
PRINT "LEFT handler"
END SUB
Пустой цикл даёт среде точки, на которых проверяется очередь. Обработчик снимается до выхода из программы, поэтому последующие нажатия LEFT снова становятся обычными событиями.