- •Тема: «Обработка событий мыши и клавиатуры»
- •1. Обработка событий мыши
- •1.1. Событие Click
- •1.2. Событие DblClick
- •1.3. События MouseDown и MouseUp
- •1.4. Событие MouseMove
- •2. Работа с клавиатурой
- •2.1. Событие KeyPress
- •2.2. События KeyDown и KeyUp
- •3. Упражнения
- •4. Задания для самостоятельного выполнения
3. Упражнения
Упражнение 1
Создадим приложение, демонстрирующее работу события MouseMove.
Реализация проекта
1. Создайте новый проект.
2. Разместите на форме массив из пяти текстовых полей Text1(0), Text1(1), Text1(2), Text1(3), Text1(4), один элемент управления PictureBox и шесть надписей (рис.13.1).
Рис. 13.1
3. Создайте процедуру для нашей формы с событием MouseMove и напишите следующий код:
Option Explicit
' переменные для записи пометок в надписях
Dim ValButton As String
Dim ValShift As String
' процедура для формы с событием MouseMove
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
Label1.Caption = "Мышь работает с формой"
'в зависимости от значения Button определяем, какая клавиша мыши нажата
If Button = 0 Then
ValButton = " Ни одной кнопки мыши не нажато" ElseIf Button = 1 Then ValButton = " Нажата левая кнопка мыши" ElseIf Button = 2 Then ValButton = " Нажата правая кнопка мыши" ElseIf Button = 4 Then ValButton = " Нажата средняя кнопка мыши" ElseIf Button = 3 Then ValButton = " Нажаты левая и правая кнопки мыши" ElseIf Button = 7 Then ValButton = " Нажаты все три кнопки мыши" End If Label2.Caption = "Значение Button= " & Button & ValButton
'в зависимости от значения Shift определяем, какая комбинация из кнопок
'SHIFT-CTRL-ALT нажата If Shift = 0 Then ValShift = " Ни одна из клавиш не нажата" ElseIf Shift = 1 Then ValShift = " Нажата клавиша SHIFT" ElseIf Shift = 2 Then ValShift = " Нажата клавиша CTRL" ElseIf Shift = 4 Then ValShift = " Нажата клавиша ALT" ElseIf Shift = 3 Then ValShift = " Нажаты клавиши SHIFT и CTRL" ElseIf Shift = 6 Then ValShift = " Нажаты клавиши ALT и CTRL" ElseIf Shift = 5 Then ValShift = " Нажаты клавиши SHIFT и ALT" ElseIf Shift = 7 Then ValShift = " Нажаты все три клавиши SHIFT-CTRL-ALT" End If Label3.Caption = "Общее состояние клавиш SHIFT-CTRL-ALT - " & Shift & _
" ;" & ValShift 'выводим координаты мыши Label4.Caption = "Координата x= " & X & " твипов" Label5.Caption = "Координата y= " & Y & " твипов" Label6.Caption = "Массива из форм Control Array быть не может" End Sub
Запустите программу. Видно, что все кнопки и клавиши отслеживаются только тогда, когда мышь движется.
4. Обратите внимание, что все нажатия кнопок и клавиш, а также изменение координат происходит только тогда, когда курсор мыши находится над формой. Как только мы перемещаемся на любой объект, TextBox или PictureBox, видимых изменений не происходит. Поскольку мы написали процедуру для формы, над другими объектами она не работает. Кроме того, координаты возвращаются внутри именно того объекта, над которым находится мышь. Т.е., если мышь находится над PictureBox'ом, значит и координаты будут PictureBox'а, а не формы Form1.
Для того, чтобы наша программка работала над всеми объектами, создадим аналогичные процедуры для объектов PictureBox и массива TextBox'ов Text1:
Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single) Label1.Caption = "Мышь работает с PictureBox" If Button = 0 Then
ValButton = " Ни одной кнопки мыши не нажато" ElseIf Button = 1 Then ValButton = " Нажата левая кнопка мыши" ElseIf Button = 2 Then ValButton = " Нажата правая кнопка мыши" ElseIf Button = 4 Then ValButton = " Нажата средняя кнопка мыши" ElseIf Button = 3 Then ValButton = " Нажаты левая и правая кнопки мыши" ElseIf Button = 7 Then ValButton = " Нажаты все три кнопки мыши" End If Label2.Caption = "Значение Button= " & Button & ValButton
If Shift = 0 Then ValShift = " Ни одна из клавиш не нажата" ElseIf Shift = 1 Then ValShift = " Нажата клавиша SHIFT" ElseIf Shift = 2 Then ValShift = " Нажата клавиша CTRL" ElseIf Shift = 4 Then ValShift = " Нажата клавиша ALT" ElseIf Shift = 3 Then ValShift = " Нажаты клавиши SHIFT и CTRL" ElseIf Shift = 6 Then ValShift = " Нажаты клавиши ALT и CTRL" ElseIf Shift = 5 Then ValShift = " Нажаты клавиши SHIFT и ALT" ElseIf Shift = 7 Then ValShift = " Нажаты все три клавиши SHIFT-CTRL-ALT" End If Label3.Caption = "Общее состояние клавиш SHIFT-CTRL-ALT - " & Shift & _
" ;" & ValShift Label4.Caption = "Координата x= " & X & " твипов" Label5.Caption = "Координата y= " & Y & " твипов" Label6.Caption = "Массива из PictureBox'ов сейчас нет" End Sub
Private Sub Text1_MouseMove(Index As Integer, Button As Integer, _
Shift As Integer, X As Single, Y As Single) Label1.Caption = "Мышь работает с массивом TextBox'ов" If Button = 0 Then
ValButton = " Ни одной кнопки мыши не нажато" ElseIf Button = 1 Then ValButton = " Нажата левая кнопка мыши" ElseIf Button = 2 Then ValButton = " Нажата правая кнопка мыши" ElseIf Button = 4 Then ValButton = " Нажата средняя кнопка мыши" ElseIf Button = 3 Then ValButton = " Нажаты левая и правая кнопки мыши" ElseIf Button = 7 Then ValButton = " Нажаты все три кнопки мыши" End If Label2.Caption = "Значение Button= " & Button & ValButton
If Shift = 0 Then ValShift = " Ни одна из клавиш не нажата" ElseIf Shift = 1 Then ValShift = " Нажата клавиша SHIFT" ElseIf Shift = 2 Then ValShift = " Нажата клавиша CTRL" ElseIf Shift = 4 Then ValShift = " Нажата клавиша ALT" ElseIf Shift = 3 Then ValShift = " Нажаты клавиши SHIFT и CTRL" ElseIf Shift = 6 Then ValShift = " Нажаты клавиши ALT и CTRL" ElseIf Shift = 5 Then ValShift = " Нажаты клавиши SHIFT и ALT" ElseIf Shift = 7 Then ValShift = " Нажаты все три клавиши SHIFT-CTRL-ALT" End If Label3.Caption = "Общее состояние клавиш SHIFT-CTRL-ALT - " & Shift & _
" ;" & ValShift Label4.Caption = "Координата x= " & X & " твипов" Label5.Caption = "Координата y= " & Y & " твипов" Label6.Caption = "Мышь находится над " & "Text1(" & Index & ")" End Sub
8. Сохраните и протестируйте проект.
Упражнение 2
Создадим программу, которая при наведении указателя мыши на кнопку с надписью "Да" перемещала бы эту кнопку в пределах формы.
Реализация проекта
1. Создайте новый проект.
2. Разместите на форме кнопки "Да", "Нет" и надпись: "Хотите ли вы получить прибавку к зарплате?".
Рис. 13.2
3. Настроим свойства кнопки с надписью "Да" таким образом, чтобы на нее нельзя было перевести фокус ввода. Для этого свойству TabStop кнопки с надписью "Да" присвойте значение False.
4. Код для кнопки "Да":
Private Sub Command1_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
Randomize
Command1.Left = Rnd * (Form1.ScaleWidth - Command1.Width - 50)
Command1.Top = Rnd * (Form1.ScaleHeight - Command1.Height - 50)
End Sub
5. Сохраните и протестируйте проект.
Каждый раз, когда пользователь наводит указатель мыши на кнопку "Да", кнопка случайным образом меняет положение на форме. Значит, с помощью мыши он не сможет нажать на кнопку.
Рис. 13.3. Программа с убегающей кнопкой в действии
Примечание. Кнопки на формах можно нажимать не только с помощью мыши. Если на кнопке установлен фокус ввода (он перемещается по элементам управления по нажатию клавиши Tab на клавиатуре), "нажать" на кнопку можно, нажав клавишу Пробел или Enter. Свойство Tabstop кнопки "Да" мы установили равным False – то есть кнопка не сможет получить фокус ввода и ее нельзя будет нажать даже с использованием клавиатуры.
6. Доработайте проект так, чтобы при нажатии на кнопку "Нет" выводилась надпись "Спасибо за участие в опросе" и программу завершала свою работу.
Упражнение 3
Создадим приложение, в котором происходит рисование с помощью мыши, как в графических редакторах.
Реализация проекта
1. Создайте новый проект.
2. Установите свойства формы: Name – frmPaint, Caption – Рисование на форме.
3. Обычно рисование происходит при движении мыши, т.е. нашему приложению необходимо обрабатывать событие MouseMove, которое сообщает, что мышь перемещается по окну приложения. Добавим следующий код:
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
frmPaint.PSet (X, Y)
End Sub
Запустим приложение. При движении мыши по форме остается след из точек.
Рис. 13.4
4. Но след должен оставаться, только если при движении мыши нажата левая кнопка мыши. Добавим это условие в код приложения.
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = 1 Then frmPaint.PSet (X, Y)
End Sub
Рис. 13.5
5. Если запустить только что созданную программу, то можно обнаружить небольшую проблему. Проблема состоит в том, что для того, чтобы нарисовать сплошную линию, нам необходимо двигать курсор мыши очень медленно. Как с этой проблемой справляются другие графические приложения? Очень просто. Они соединяют линией две соседние точки положения мыши. Это может показаться странным, но именно так работают графические редакторы.
Во время движения мыши по экрану компьютер проверяет положение мыши через небольшие промежутки времени. Поскольку компьютер не имеет возможности отследить все положения мыши, то необходимо делать некоторые предположения о ее местонахождении. Это предположение выражается в том, что компьютер предполагает, что мышь двигалась по прямой между теми двумя точками, положение которых компьютеру известно. Когда вы рисуете на компьютере с помощью мыши, компьютер ведет себя именно так.
Повторим этот метод в нашем приложении.
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = 1 Then frmPaint.Line -(X, Y)
End Sub
Рис. 13.6
6. Почти хорошо. Однако появилась неприятная особенность. Каждый раз, когда мы нажимаем кнопку мыши для того, чтобы начать рисовать новый фрагмент, приложение соединяет линией точку окончания предыдущего фрагмента с началом нового. Для этого нам понадобится знать начальное положение курсора мыши при нажатии кнопки. Объявим две переменные в секции (General)(Declarations), перепишем процедуру обработки события MouseMove и добавим обработку события MouseDown.
Option Explicit
Dim intPrevX As Integer
Dim intPrevY As Integer
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = 1 Then frmPaint.Line (intPrevX, intPrevY)-(X, Y)
intPrevX = X
intPrevY = Y
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = 1 Then
intPrevX = X
intPrevY = Y
End If
End Sub
Готово! Запускаем приложение и радуемся результату.
Рис. 13.7
Радуемся, радуемся, но если приложение свернуть и обратно развернуть (или на время закрыть другим окном) изображение исчезнет. Избавиться от этой неприятности просто: установите свойство формы AutoRedraw равным True и окно будет перерисовываться автоматически.
7. Создадим цветной рисунок. По умолчанию будем использовать черный цвет. Другие цвета можно будет включить, нажав на определенную клавишу на клавиатуре, вернуться к черному цвету, нажав на любую другую клавишу.
Текущий цвет будем хранить в переменной Color типа Long. Значение переменной можно задать различными способами:
присвоив какое-то числовое значение (Color = 12345; Color = &H80000018);
с помощью констант (Color = vbBlack);
с помощью функции QBColor() (Color = QBColor(3));
с помощью функции RGB() (Color = RGB(255,255,255)).
Дополним уже имеющийся код:
Option Explicit
Dim intPrevX As Integer
Dim intPrevY As Integer
Dim Color As Long
Private Sub Form_Load()
Color = RGB(0, 0, 0)
End Sub
Private Sub Form_KeyPress(KeyAscii As Integer)
Select Case Chr$(KeyAscii)
Case "1"
Color = RGB(255, 0, 0)
Case "2"
Color = RGB(0, 255, 0)
Case "3"
Color = RGB(0, 0, 255)
Case Else
Color = RGB(0, 0, 0)
End Select
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = 1 Then frmPaint.Line (intPrevX, intPrevY)-(X, Y), Color
intPrevX = X
intPrevY = Y
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = 1 Then
intPrevX = X
intPrevY = Y
End If
End Sub
8. Сохраните и протестируйте проект.
Рис. 13.8
9. Доработайте проект так, чтобы при щелчке по правой кнопке мыши толщина линии возрастала на 1.
Упражнение 4
Создадим приложение, в котором по нажатию одной из стрелок объект будет передвигаться по экрану в направлении, соответствующем стрелке. То есть, если вы нажали на стрелку вверх, то объект должен передвинуться вверх и т.п.
Реализация проекта
1. Создайте новый проект.
2. Разместите на форме элемент управления Shape. Можете сделать эту фигуру чем угодно, хоть квадратом, хоть кругом, это не имеет значения.
3. Программный код приложения:
Option Explicit
Dim x As Integer, y As Integer
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
' Присваиваем переменной х значение положения объекта по горизонтали
x = Shape1.Left
' Присваиваем переменной y значение положения объекта по вертикали
y = Shape1.Top
' Если код нажатой клавиши равен 37 (стрелка влево),
' то от значения переменной x отнять 50
If KeyCode = 37 Then x = x – 50
' Если код нажатой клавиши равен 39 (стрелка вправо),
' то к значению переменной x прибавить 50
If KeyCode = 39 Then x = x + 50
' Если код нажатой клавиши равен 38 (стрелка вверх),
' то от значения переменной y отнять 50
If KeyCode = 38 Then y = y - 50
' Если код нажатой клавиши равен 40 (стрелка вниз),
' то к значению переменной y прибавить 50
If KeyCode = 40 Then y = y + 50
' Присваиваем значению горизонтального положения объекта значение
' переменной x
Shape1.Left = x
' Присваиваем значению вертикального положения объекта значение
' переменной y
Shape1.Top = y
End Sub
4. Сохраните и протестируйте проект.
Рис. 13.9. Управление объектом
Примечание. Если на форме находятся управляющие элементы (кнопки и т.д.), то программа не будет работать из-за того, что фокус находиться не на форме, а на одном из этих элементов.
