Я разработал приложение, использующее vb.net, которое указывает статус блокировки кепки моей системы. В основной форме есть флажок, всякий раз, когда блокировка колпаков включается, нажимая клавишу блокировки колпачков, флажок устанавливается, и при выключении флажок не снимается. Ниже приведены коды:Как поднять события, когда моя форма не имеет фокуса (vb .net)
Public Class Form1
Dim keyStCL As Boolean = False
Private WithEvents KeyHook As New KeyboardHook
Private Const VK_CAPSLOCK As Integer = &H14
Private Const VK_SCROLLLOCK 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 SimulateKeyPressCaps(ByVal bVKCode As Byte, ByVal bScanCode As Byte)
Call keybd_event(VK_CAPSLOCK, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0)
Call keybd_event(VK_CAPSLOCK, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
End Sub
Private Sub checkbutton_caps_CheckedChanged(sender As Object, e As EventArgs) Handles checkbutton_caps.Click
If keyStCL = True Then
SimulateKeyPressCaps(VK_CAPSLOCK, &H45)
checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_off.png")
checkbutton_caps.Checked = False
ElseIf keyStCL = False Then
SimulateKeyPressCaps(VK_CAPSLOCK, &H45)
checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_on.png")
checkbutton_caps.Checked = True
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Activated
Me.KeyPreview = True
If My.Computer.Keyboard.CapsLock = True Then
keyStCL = True
My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)
checkbutton_caps.Checked = True
checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_on.png")
ElseIf My.Computer.Keyboard.CapsLock = False Then
keyStCL = False
checkbutton_caps.Checked = False
checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_off.png")
End If
Private Sub Form1_KeyPressCaps(ByVal sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.CapsLock Then
If keyStCL = True Then
checkbutton_caps.Checked = False
checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_off.png")
keyStCL = False
ElseIf keyStCL = False Then
checkbutton_caps.Checked = True
checkbutton_caps.Image = Image.FromFile("resources\btn_ico_caps_on.png")
keyStCL = True
End If
End If
End Sub
Теперь проблема все события, упомянутые в приведенных выше кодов получить рейз только тогда, когда основной формой имеет фокус и не тогда, когда он потерял фокус. Я планирую запустить эту программу в фоновом режиме, чтобы всякий раз, когда я нажимал клавишу блокировки caps, я получаю уведомление, но это невозможно, поскольку события клавиатуры не возникают, когда программа потеряла фокус. Как я могу сделать свою программу поднять события, даже если у нее нет фокуса?
И ниже - класс клавиатуры, который я использовал. (Я ничего не изменил в классе Keyboard Hook, я использовал его, поскольку он находится на https://sim0n.wordpress.com/2009/03/28/vbnet-keyboard-hook-class/) После использования этого класса я теперь получаю сообщение об ошибке: Не удалось установить Keyboard Hook. Это сообщение об ошибке было создано самим классом Keyboard Hook.
Imports System.Runtime.InteropServices
Public Class KeyboardHook
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
End Function
<StructLayout(LayoutKind.Sequential)> _
Private Structure KBDLLHOOKSTRUCT
Public vkCode As UInt32
Public scanCode As UInt32
Public flags As KBDLLHOOKSTRUCTFlags
Public time As UInt32
Public dwExtraInfo As UIntPtr
End Structure
<Flags()> _
Private Enum KBDLLHOOKSTRUCTFlags As UInt32
LLKHF_EXTENDED = &H1
LLKHF_INJECTED = &H10
LLKHF_ALTDOWN = &H20
LLKHF_UP = &H80
End Enum
Public Shared Event KeyDown(ByVal Key As Keys)
Public Shared Event KeyUp(ByVal Key As Keys)
Private Const WH_KEYBOARD_LL As Integer = 13
Private Const HC_ACTION As Integer = 0
Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Private Const WM_SYSKEYDOWN = &H104
Private Const WM_SYSKEYUP = &H105
Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc)
Private HHookID As IntPtr = IntPtr.Zero
Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
If (nCode = HC_ACTION) Then
Dim struct As KBDLLHOOKSTRUCT
Select Case wParam
Case WM_KEYDOWN, WM_SYSKEYDOWN
RaiseEvent KeyDown(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
Case WM_KEYUP, WM_SYSKEYUP
RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
End Select
End If
Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
End Function
Public Sub New()
HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
If HHookID = IntPtr.Zero Then
Throw New Exception("Could not set keyboard hook")
End If
End Sub
Protected Overrides Sub Finalize()
If Not HHookID = IntPtr.Zero Then
UnhookWindowsHookEx(HHookID)
End If
MyBase.Finalize()
End Sub
End Class
Возможный дубликат [Как слушать клавиатуру в фоновом режиме и нажатия клавиш по требованию?] (Http://stackoverflow.com/questions/15038413/how-to-listen-keyboard -in-background-and-fire-keystrokes-on-demand) –
Вы можете достичь этого только с помощью глобального ключевого крючка – Mono
Переходя на вопрос о http://stackoverflow.com/questions/15038413/how-to-listen-keyboard -in-background-and-fire-keystrokes-on-demand Я использовал класс клавиатуры для клавиатуры и теперь получаю сообщение об ошибке: Не удалось установить клавиатурный крючок – Xlam