События KeyDown и KeyUp. Класс KeyEventArgs
KeyDown и KeyUp. Создайте проект из одной формы, без элементов управления. Введите такой код:
Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles MyBase.KeyPress
Debug.WriteLine("Сработал KeyPress")
End Sub
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles MyBase.KeyDown
Debug.WriteLine("Сработал KeyDown")
End Sub
Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs) Handles MyBase.KeyUp
Debug.WriteLine("Сработал KeyUp")
End Sub
Запустите проект, пощелкайте по клавишам клавиатуры и понаблюдайте за результатами в окне Output. Удерживайте нажатыми разные клавиши и тоже наблюдайте.
Выводы: При нажатии почти любой клавиши клавиатуры срабатывает событие KeyDown. Если при этом нажатие приводит к вводу символа, то сразу за ним срабатывает событие KeyPress. Если вы удерживаете клавишу нажатой, эта парочка срабатывает многократно и часто. При отпускании клавиши однократно срабатывает событие KeyUp. Я не рассматриваю ситуацию, когда одновременно удерживаются нажатыми две и более клавиш.
KeyCode. Какие именно клавиши клавиатуры были нажаты или отпущены, вам подскажет свойство KeyCode объекта e, принадлежащего классу KeyEventArgs. Введите такой код:
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e KeyEventArgs) Handles MyBase.KeyDown
Debug.WriteLine(e.KeyCode.ToString)
End Sub
Пояснения: Здесь я использовал свойственный объектам метод ToString, который возвращает в виде вразумительной строки имя или значение объекта.
Запустите проект, пройдитесь по всем клавишам клавиатуры (кроме тех, конечно, что выключают компьютер). Вот что вы увидите:
Печать в окне Output | Какая клавиша была нажата | ||
D
L F1 Tab Enter Left Space D1 D2 Escape ControlKey ShiftKey Menu | D
L F1 Tab Enter Стрелка влево Пробел Цифра 1 Цифра 2 Esc Ctrl Shift Alt |
И так далее. Пройдитесь по клавишам дополнительной цифровой клавиатуры в правой части клавиатуры при включенном и выключенном индикаторе NumLock.
Свойства Control, Alt, Shift. VB позволяет определить, какие из трех клавиш Ctrl, Alt, Shift удерживались нажатыми в момент срабатывания события KeyDown или KeyUp. Дополните процедуру:
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles MyBase.KeyDown
Debug.WriteLine(e.KeyCode.ToString & " " & e.Control
& " " & e.Alt & " " & e.Shift)
End Sub
Здесь я использовал свойства Control, Alt, Shift объекта e. Их смысл будет ясен из распечатки в окне Output. Запустите проект, нажмите и удерживайте нажатыми клавиши Alt и Shift (но не Ctrl), после чего щелкните по клавише W. Вот что вы увидите последней напечатанной строкой в окне Output:
W False True True
Все сказанное относится и к событию KeyUp.
Анализировать нажатия клавиш для управления компьютером можно, например, такими операторами:
If e.KeyCode = Keys.F2 Then Debug.WriteLine("Нажата клавиша F2")
If e.Shift Then Debug.WriteLine("Нажата клавиша Shift")
If e.Control And e.KeyCode
= Keys.Right Then Debug.WriteLine("Нажата стрелка направо при нажатой кл Ctrl")
Перечисление Keys включает в себя коды клавиш клавиатуры.
События клавиатуры у элементов управления. События, связанные с клавиатурой, имеются у многих элементов управления. Поместим на форму, к примеру, пару кнопок и текстовое поле. Вдобавок к процедуре Form1_KeyDown напишем три процедуры:
Private Sub Button1_KeyDown …
Private Sub Button2_KeyDown …
Private Sub TextBox1_KeyDown …
Запустим программу и щелкнем по какой-нибудь клавише. Какая из четырех процедур сработает? Та, чей элемент управления находится в фокусе. А поскольку один какой-нибудь элемент на форме всегда находится в фокусе, до процедуры Form1_KeyDown дело никак не доходит. Это не всегда бывает удобно. И против этого в VB есть специальный прием: свойство формы KeyPreview устанавливается в True. Это означает приказ компьютеру при нажатии на клавишу сначала вызывать событие формы, а уж потом другого объекта. Так, если в фокусе находится кнопка 2, то при нажатии на клавишу клавиатуры сначала выполняется процедура Form1_KeyDown, а сразу за ней – Button2_KeyDown. Сказанное касается большинства клавиш и элементов управления, но не всех.
«Телефонный номер». Разберем пример использования событий клавиатуры. Пусть на форме имеется текстовое поле, которое мы предназначили для ввода телефонных номеров. Сделаем текстовое поле умным – запретим ему воспринимать символы за исключением цифр, пробелов, черточек и точек. Если пользователь попытается ввести неподходящий символ, должно появляться сообщение об ошибке, а сам символ в поле появляться не должен. После окончания ввода можно нажать клавишу Enter, пусть при этом выводится сообщение «Ввод закончен».
Вот код:
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _
Handles TextBox1.KeyPress
Dim С As Char = e.KeyChar 'Вводимый символ
If Char.IsDigit(С) Or Char.IsSeparator(С) Or С = "-" Or С = "." Then Exit Sub
Beep()
MsgBox("В телефонном номере можно употреблять только цифры, пробелы, черточки и точки!")
e.Handled
= True
End Sub
Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode = Keys.Enter Then MsgBox("Ввод закончен")
End Sub
Пояснения: Используются события KeyPress и KeyDown текстового поля. Событие KeyDown используется для обработки нажатия на клавишу Enter. Оператор If в первой процедуре предназначен для того, чтобы не создавать проблем цифрам, пробелам, черточкам и точкам. Ведь выход из процедуры (Exit Sub) и есть выход без проблем. Если символ не принадлежит к упомянутым, то выхода из процедуры не происходит и выполняются последние три строки процедуры: раздается сигнал, затем появляется сообщение, а напоследок оператор e.Handled = True заставляет компьютер считать, что неосуществленная стандартная обработка события (в частности – появление символа в текстовом поле) якобы уже произошла, а значит и символу незачем появляться в текстовом поле.
Задание 97.
«Управляемый объект». На клавиатуре имеются четыре клавиши со стрелками для управления курсором. Поместите на форму какой-нибудь элемент управления. При щелчке по любой клавише управления курсором элемент управления должен двигаться с постоянной скоростью в указанном на клавише направлении.
Задание 98.
«Светофор». Нарисуйте светофор: прямоугольник и три круга. При наборе на клавиатуре символа R светофор должен загораться красным светом, G – зеленым, Y - желтым.
Задание 99.
«Зенитка». Вверху справа налево медленно движется вражеский самолет. В подходящий момент вы нажатием любой клавиши запускаете снизу вверх зенитный снаряд. При попадании компьютер выдает соответствующее сообщение.
Не шали! Поставьте при помощи событий клавиатуры преграду тем шалунам, кто в нашем калькуляторе хочет ввести с клавиатуры в текстовое поле для результата любые символы. А потом вспомните, что это можно было сделать, просто превратив текстовое поле в метку или придав текстовому полю свойство ReadOnly.