KeyboardEvents.OnKeyPress Event

Автор Тема: KeyboardEvents.OnKeyPress Event  (Прочитано 18254 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
KeyboardEvents.OnKeyPress Event
« : 19-01-2015, 13:58:10 »
Доброго времени суток, уважаемые форумчане. Помогите пожалуйста разобраться, как  программно выполнить какое-нибудь действие, при нажатии на какую-нибудь клавишу клавиатуры. Например как сделать так, чтобы при нажатии "Esc" закрывалась открытая ранее форма. Сам разобраться с синтаксисом не смог :(
В программировании я новичок...но ненадолго! ;)

Отмечено как Решение R.I.Chernov 20-01-2015, 11:39:13

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: KeyboardEvents.OnKeyPress Event
« Ответ #1 : 20-01-2015, 09:19:20 »
R.I.Chernov,
попробую ответить. Хоть я ни разу с Inventor API не работал, но вопрос по сути общего характера.
Речь идет о VBA или VB.NET? В любом случае, нужно подписаться на событие KeyPress. В обработчике события, одним из параметров будет нажатая клавиши. Нужно сверить нажатую клавишу с Esc и если условие выполняется, закрыть форму.
На VBA это будет выглядеть вот так:
Код - Visual Basic [Выбрать]
  1. Private Sub UserForm_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
  2.     If (KeyAscii = 27) Then
  3.         Me.Hide
  4.     End If
  5. End Sub
На VB.NET:
Код - vb.net [Выбрать]
  1.     Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MyBase.KeyPress
  2.         If (e.KeyChar = Chr(27)) Then
  3.             Close()
  4.         End If
  5.     End Sub

Не трудно заметить, что в данном случае необходимо использования числового кода клавиши Esc, что не слишком явно, так как число 27 нужно еще как-то получить.
Поэтому конкретно для описанного варианта лушче использовать событие KeyDown или KeyUp возникающее при нажатии клавиши или при отпускании соответственно.
В параметрах этих событий, нужно использовать уже не числовой код, а предопределенный.
VBA:
Код - Visual Basic [Выбрать]
  1. Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  2.     If (KeyCode = KeyCodeConstants.vbKeyEscape) Then
  3.         Me.Hide
  4.     End If
  5. End Sub

VB.NET:
Код - vb.net [Выбрать]
  1.     Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
  2.         If e.KeyCode = Keys.Escape Then
  3.             Close()
  4.         End If
  5.     End Sub

В VB.NET есть еще один, более элегантный способ закрытия формы по Esc. Если все же используется он, то опишу в другом сообщении.

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Re: KeyboardEvents.OnKeyPress Event
« Ответ #2 : 20-01-2015, 11:45:20 »
Спасибо, Виктор! Код  работает (по крайней мере для VBA :) ).
Если этот топик вдруг читают такие же "высококвалифицированные" программисты как я, то стоит пояснить,  что Private Sub UserForm_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) это событие,и его надо поместить в код формы :)

Но если честно, то, помимо помощи в решении, вы создали в моей голове огромную кучу вопросов и ощущение еще большего непонимание этой темы :)
Попробую сформулировать некоторые из них:
1. в справке VBA в инвентор написано:
    Private Sub object_KeyDown( ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As fmShiftState)Почему в вашем примере "ByVal Shift As Integer" работает, а "ByVal Shift As fmShiftState" из справки нет?

2. Как использовать событие инвентора: KeyboardEvents.OnKeyPress Event?
Я вроде бы понял, как можно до него "добраться":
 
Код - Visual Basic [Выбрать]
  1. Dim KeyEvent As KeyboardEvents
  2. Set KeyEvent = ThisApplication.CommandManager.CreateInteractionEvents.KeyboardEvents
Но как ни пыхтел, я так и не смог понять, что делать дальше, чтобы вернуть какую либо переменную и воспользоваться ее значением для создания условия. В примерах справки, к сожалению, аналога нет :(

Буду очень признателен за любую помошь!
« Последнее редактирование: 20-01-2015, 12:12:12 от R.I.Chernov »
В программировании я новичок...но ненадолго! ;)

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Re: KeyboardEvents.OnKeyPress Event
« Ответ #3 : 20-01-2015, 13:35:13 »
У меня появился еще один вопрос... Виктор, Ваш код работает у меня при пустой форме (нет ни текстбоксов, ни кнопок и т.п.), если поместить в форму хотя бы один текст бокс, то при загрузке формы он становится активным, и нажатие клавиши "Esc" внутри него приводит к удалению значения внутри текст бокса, но не к активации события. Не могли бы вы подсказать, как я могу сделать текстбоксы неактивными, например при нажатии на форму, ну или еще как-нибудь, в общем как сделать так, чтобы код работал? :)
В программировании я новичок...но ненадолго! ;)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: KeyboardEvents.OnKeyPress Event
« Ответ #4 : 20-01-2015, 14:04:26 »
R.I.Chernov, быстрое гугление показало, что единственный способ, это подписаться на событие KeyPress для каждого контрола на форме.
Т.е. помимо
Код - Visual Basic [Выбрать]
  1. Private Sub UserForm_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
  2.     If (KeyAscii = 27) Then
  3.         Me.Hide
  4.     End If
  5. End Sub
вам еще понадобиться обработка события нажатия клавиши в текстовом поле.
Код - Visual Basic [Выбрать]
  1. Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
  2.     If (KeyAscii = 27) Then
  3.         Me.Hide
  4.     End If
  5. End Sub
И так для каждого контрола, который может иметь фокус на форме.

Возможно есть какое-то более изящное решение, но с VBA я уже лет 8 не работал...)

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Re: KeyboardEvents.OnKeyPress Event
« Ответ #5 : 20-01-2015, 14:45:51 »
Спасибо! Насчет элегантности я не знаю, но работает! :) Честно говоря, думал, что есть какой нибудь универсальный "unfocus" для всей формы, или что перебором можно как - нибудь хитро снять фокус сразу со всего, чтобы не дублировать для всех элементов формы данное событие. Так что, если кто в курсе более простого метода, милости просим! )))
Виктор, еще раз спасибо Вам за помощь!
П.С. Очередное пояснение для "суперпрограммистов", каких же, как я сам :) : код клавиш в формате ASCII нашел в объектном браузере в разделе "KeyCodeConstants", при наведении, например, на "vbKey0", пишется что "vbKey0 = 48".
В программировании я новичок...но ненадолго! ;)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: KeyboardEvents.OnKeyPress Event
« Ответ #6 : 20-01-2015, 14:59:30 »
П.С. Очередное пояснение для "суперпрограммистов", каких же, как я сам  : код клавиш в формате ASCII нашел в объектном браузере в разделе "KeyCodeConstants", при наведении, например, на "vbKey0", пишется что "vbKey0 = 48".
Так если нашли константы, так и используйте их, а не число:)
Код - Visual Basic [Выбрать]
  1. Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
  2.     If (KeyAscii = KeyCodeConstants.vbKeyEscape) Then
  3.         Me.Hide
  4.     End If
  5. End Sub

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Re: KeyboardEvents.OnKeyPress Event
« Ответ #7 : 20-01-2015, 15:10:51 »
Так если нашли константы, так и используйте их, а не число:)

Спасибо! Я подчеркнул это еще из первого Вашего сообщения, просто попытался сделать этот топик максимально информативным и полезным для кого-нибудь еще. Возможно нравится кому-нибудь циферками писать :)
В программировании я новичок...но ненадолго! ;)

Оффлайн Алексей Романов

  • ADN Club
  • **
  • Сообщений: 87
  • Карма: 20
Re: KeyboardEvents.OnKeyPress Event
« Ответ #8 : 21-01-2015, 08:06:23 »
Например как сделать так, чтобы при нажатии "Esc" закрывалась открытая ранее форма.
Если я правильно понял, то в VBA такое программировать не нужно. Если свойство Cancel кнопки, которая закрывает форму, установить в True (по умолчанию False), то при нажатии клавиши "Esc" форма закрывается, где бы фокус не находился...

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: KeyboardEvents.OnKeyPress Event
« Ответ #9 : 21-01-2015, 09:52:21 »
Алексей Романов, проверил. Не работает. Если кнопка добавлена, свойство Cancel установлено в True, то при нажатии Esc переводится фокус на эту кнопку, но форма не закрывается.
UPDATE:
Кажется понял. Если кнопке задать свойство Cancel=True, то при нажатии на кнопку Esc вызывается событие OnClick на этой кнопке.
Т.е. помимо свойства Cancel надо на обработку события нажатия кнопки написать код закрытия формы.
Код - Visual Basic [Выбрать]
  1. Private Sub CommandButton1_Click()
  2.     Me.Hide
  3. End Sub

Оффлайн Алексей Романов

  • ADN Club
  • **
  • Сообщений: 87
  • Карма: 20
Re: KeyboardEvents.OnKeyPress Event
« Ответ #10 : 21-01-2015, 10:17:35 »
Т.е. помимо свойства Cancel надо на обработку события нажатия кнопки написать код закрытия формы.
Совершенно верно..) Я ведь и написал, что это свойство устанавливается для той кнопки, которая закрывает форму. Я думаю, что на форме практически всегда есть кнопка для ее закрытия...

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Re: KeyboardEvents.OnKeyPress Event
« Ответ #11 : 21-01-2015, 10:40:18 »
Спасибо Алексей, за то что присоединились к нашей беседе! Ваш метод работает, за что вам второе спасибо!  :)
От себя добавлю ссылку-пояснение для "суперпрограммистов", лично я там нашел ответы на возникшие по поводу кнопки "Cancel" вопросы:
https://msdn.microsoft.com/en-us/library/office/ff821090%28v=office.15%29.aspx

П.С. Тем не менее остается еще несколько вопросов, упомянутых мною выше. Если кто-нибудь может помочь решением или просто гипотезой, буду примногоблагодарен!
В программировании я новичок...но ненадолго! ;)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: KeyboardEvents.OnKeyPress Event
« Ответ #12 : 21-01-2015, 11:04:25 »
Я ведь и написал, что это свойство устанавливается для той кнопки, которая закрывает форму.
Да это я по аналогии с .NET. Там можно вообще дополнительного кода не писать, для того, чтобы по нажатии на Esc форма закрывалась. По инерции и в VBA так же попробовал, а про обработку события не подумал сначала.

Оффлайн Алексей Романов

  • ADN Club
  • **
  • Сообщений: 87
  • Карма: 20
Re: KeyboardEvents.OnKeyPress Event
« Ответ #13 : 21-01-2015, 12:28:49 »
2. Как использовать событие инвентора: KeyboardEvents.OnKeyPress Event?
Для обработки событий в АИ в VBA используются модули классов. Если кратко, в папке Class Modules создается модуль Class1: Private WithEvents oInteraction As InteractionEvents
Private WithEvents myKey As KeyboardEvents
Private Sub Class_Initialize()
  Set oInteraction = ThisApplication.CommandManager.CreateInteractionEvents
  Set myKey = oInteraction.KeyboardEvents
  oInteraction.Start
End Sub
Private Sub Class_Terminate()
If Not oInteraction Is Nothing Then
    oInteraction.Stop
    Set myKey = Nothing
End If
End Sub
Private Sub myKey_OnKeyDown(ByVal Key As Long, ByVal ShiftKeys As ShiftStateEnum)
    If Key > 31 Then MsgBox Chr(Key)
    If Key = 27 Then
        If Not oInteraction Is Nothing Then
            oInteraction.Stop
            Set myKey = Nothing
            Set oInteraction = Nothing
            Class_Terminate
        End If
    End If
End Sub
В память он грузится процедурой в обычном модуле:Dim myKeyEvent As Class1
Sub KeyEvent()
 If Not myKeyEvent Is Nothing Then
    Set myKeyEvent = Nothing
    Set myKeyEvent = New Class1
 Else
    Set myKeyEvent = New Class1
 End If
End Sub
На форуме cad.ru я не раз об этом писал, поищи по словам Класс модуль...
« Последнее редактирование: 21-01-2015, 13:28:42 от Алексей Романов »

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Re: KeyboardEvents.OnKeyPress Event
« Ответ #14 : 21-01-2015, 13:26:31 »
Спасибо за идею! Буду разбираться.
В программировании я новичок...но ненадолго! ;)