2016-05-28 3 views
0

Я разработал приложение (с vb .net), которое может переключать состояние блокировки колб, нажав на флажок. Я закодировал программу таким образом, что, когда я нажимаю на этот флажок, если он проверяется, блокировка колпачка должна быть включена, и если он не установлен, он должен отключиться. Ниже приведены коды.Проблема с блокировкой колпачков с флажком vb .net

Public Class Form1 

Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer) 

Private Const VK_CAPITAL As Integer = &H14 
Private Const VK_SCROLL As Integer = &H91 
Private Const VK_NUMLOCK As Integer = &H90 

Private Const KEYEVENTF_EXTENDEDKEY As Integer = &H1 
Private Const KEYEVENTF_KEYUP As Integer = &H2 

Private Sub checkbutton_caps_CheckedChanged(sender As Object, e As EventArgs) Handles checkbutton_caps.CheckStateChanged 

    If checkbutton_caps.Checked = True Then 
     Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0) 
     checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_on.png") 

    ElseIf checkbutton_caps.Checked = False Then 
     Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0) 
     checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_off.png") 

    End If 
End Sub 
End Class 

Теперь проблема в том, что она не работает должным образом. Если я установил флажок, изменится только изображение флажка, но не состояние блокировки колпачка. Статус блокировки блокировки изменяется только тогда, когда я дважды нажимаю на флажок. Поэтому мне нужно дважды щелкнуть по флажку, чтобы переключить блокировку колпачков. Я подозреваю, что есть проблема в том, как я использовал условные утверждения.

+0

... Почему? Является ли ваш ключ блокировки кнопок сломанным? –

+0

@CodyGray Нет, его не сломал, я просто хочу создать виртуальную клавиатуру. – Xlam

+1

Пуск -> Выполнить -> osk.exe –

ответ

1

Проблема не условная логика по себе (другими словами, вы написали If заявление правильно), а то, как вы используете функцию keybd_event.

Подумайте о физических клавишах на клавиатуре. Когда вы «нажимаете» клавишу, на самом деле происходят две вещи: клавиша идет вниз, а затем возвращается ключ. После происходит как, так и событие нажатия клавиши регистрируется как имевшее место.

Таким образом, правильный способ запуска нажатия клавиши с использованием функции keybd_event - это ввести событие «вниз», а затем событие «Key-up». Поэтому вам действительно нужна пара вызовов:

Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0) 
Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0) 

Теперь, когда вы это понимаете, оглянитесь на свой код. Элемент управления флажком не установлен. При первом нажатии на него он автоматически проверяется, и ваш обработчик события CheckedChanged срабатывает. В ответ вы делаете первый звонок на номер keybd_event, который по существу «нажимает» клавишу блокировки крышки. Он не до времени второго вы щелкните элемент управления флажком, переключая его назад непроверенный и сделать вызов второго к keybd_event, что вы на самом деле вызвать полный пресс колпачков блокировки ключа.

Написать код так:

Private Sub checkbutton_caps_CheckedChanged(sender As Object, e As EventArgs) Handles checkbutton_caps.CheckStateChanged 

    If checkbutton_caps.Checked = True Then 
     Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0) 
     Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0) 
     checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_on.png") 

    ElseIf checkbutton_caps.Checked = False Then 
     Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0) 
     Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0) 
     checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_off.png") 

    End If 

End Sub 

Или, еще лучше, инкапсулирует логику, чтобы вызвать нажатие клавиши в другой функции, уменьшение дублирования кода:

Private Sub SimulateKeyPress(ByVal bVKCode As Byte, ByVal bScanCode As Byte) 
    keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0) 
    keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0) 
End Sub 

Private Sub checkbutton_caps_CheckedChanged(sender As Object, e As EventArgs) Handles checkbutton_caps.CheckStateChanged 

    If checkbutton_caps.Checked = True Then 
     SimulateKeyPress(VK_CAPITAL, &H45) 
     checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_on.png") 

    ElseIf checkbutton_caps.Checked = False Then 
     SimulateKeyPress(VK_CAPITAL, &H45) 
     checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_off.png") 

    End If 

End Sub 

Даже лучше еще , используйте SendInput function вместо устаревшей функции keybd_event. Это позволяет, помимо прочего, проверять и обрабатывать ошибки.

Обратите внимание, что в VB.NET вам не нужен синтаксис Call. Это старая вещь VB 6, а не идиоматический способ писать код в VB.NET.

+0

Спасибо за ответ, проблема решена. Я никогда не знал, как работают ключевые события в прессе, иначе я бы не допустил этой ошибки. – Xlam

+0

'сокращение кода duplication', если это так, почему не так:' Private Sub checkbutton_caps_CheckedChanged (отправитель As Object, е Как EventArgs) Ручки checkbutton_caps.CheckStateChanged keybd_event (VK_CAPITAL, & H45, KEYEVENTF_EXTENDEDKEY или 0, 0) keybd_event (VK_CAPITAL, & H45 , KEYEVENTF_EXTENDEDKEY Или KEYEVENTF_KEYUP, 0) checkbutton_caps.Image = Image.FromFile (CStr (IF (checkbutton_caps.Checked, "ресурсы \ btn_ico_caps_on.png", "ресурсы \ btn_ico_caps_off.png"))) End Sub' – Codexer

+0

@Cody Серый Также что-то еще, чтобы указать, ** метод **, а не *** функция *** 'SimulateKeyPress' вообще не использует аргументы, почему даже классифицировать их и не использовать? Нет необходимости даже в том, чтобы этот метод говорил о сокращении кода ... Хорошее решение. – Codexer

Смежные вопросы