Imports System.Runtime.InteropServices
Public NotInheritable Class HotkeyManager
'**************** [Delegates] **************
Public Delegate Sub HotkeyCallback(ByVal pParams As Object())
Private Delegate Function HookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
'************** [End Delegates] ************
Private Const WH_KEYBOARD_LL As Integer = &HD 'constant for a low-level keyboard hook.
'********* [Windows API Functions] *********
<DllImport("user32.dll", CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal pHook As HookProc, ByVal hMod As IntPtr, ByVal dwThreadId As UInteger) As IntPtr
End Function
<DllImport("user32.dll", CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function UnhookWindowsHookEx(ByVal hHook As IntPtr) As Integer
End Function
<DllImport("user32.dll", CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
'******* [End Windows API Functions] *******
'*********** [Instance Variables] **********
Private Shared __hhook As IntPtr
Private Shared __hotkeys As Dictionary(Of Integer, Hotkey)
Private Shared __ishk As Boolean
Public Shared Property IsHooked() As Boolean
Get
Return HotkeyManager.__ishk
End Get
Private Set(ByVal value As Boolean)
HotkeyManager.__ishk = value
End Set
End Property
'********* [End Instance Variables] ********
' Initialize the hook if it isn't already. This has to be called before the hook will work.
Public Shared Sub Initialize()
If Not HotkeyManager.IsHooked Then 'check if the hook has already been initialized.
Dim pBaseModule As ProcessModule = Process.GetCurrentProcess().MainModule
Dim pBaseAddress As IntPtr = CType(If(pBaseModule IsNot Nothing, pBaseModule.BaseAddress, New IntPtr(0)), IntPtr)
HotkeyManager.__hhook = SetWindowsHookEx(WH_KEYBOARD_LL, New HookProc(AddressOf KeyboardCallback), pBaseAddress, 0)'attempt to set the hook.
HotkeyManager.IsHooked = (HotkeyManager.__hhook <> IntPtr.Zero)
If HotkeyManager.__hotkeys Is Nothing Then
'if need be, initialize the dictionary for use.
HotkeyManager.__hotkeys = New Dictionary(Of Integer, Hotkey)()
End If
End If
End Sub
'turn the manager off, to turn it back on just call Initialize again.
Public Shared Sub Disable()
HotkeyManager.IsHooked = (UnhookWindowsHookEx(HotkeyManager.__hhook) <> 0)
End Sub
'Unset the hook and reset the key list.
Public Shared Sub Destroy()
HotkeyManager.__hotkeys = Nothing
HotkeyManager.IsHooked = (UnhookWindowsHookEx(HotkeyManager.__hhook) <> 0)
End Sub
'internal callback method. Will trigger a hotkey event only when the key is pressed down.
Private Shared Function KeyboardCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
Dim l_param As Integer = Marshal.ReadInt32(lParam) 'read the keycode.
If wParam.ToInt32() = &H100 AndAlso HotkeyManager.__hotkeys.ContainsKey(l_param) Then 'check if this is a keydown, and if the hotkey is internally registered.
Dim hCallback As HotkeyCallback = HotkeyManager.__hotkeys(l_param).Callback
hCallback(HotkeyManager.__hotkeys(l_param).Paramet ers)
End If
Return CallNextHookEx(HotkeyManager.__hhook, nCode, wParam, lParam)
End Function
'register a hotkey if it doesn't already exist with a provided callback.
Public Shared Sub RegisterHotkey(ByVal key As Integer, ByVal hkproc As HotkeyCallback, ByVal oParams As Object())
If Not HotkeyManager.__hotkeys.ContainsKey(key) AndAlso hkproc IsNot Nothing Then
HotkeyManager.__hotkeys.Add(key, New Hotkey() With {.Callback = hkproc, .Parameters = oParams})
End If
End Sub
'Clear an existing hotkey if it exists.
Public Shared Sub UnregisterHotkey(ByVal key As Integer)
If HotkeyManager.__hotkeys.ContainsKey(key) Then
HotkeyManager.__hotkeys.Remove(key)
End If
End Sub
Private Structure Hotkey
Public Callback As HotkeyCallback
Public Parameters As Object()
End Structure
End Class
HotkeyManager.Initialize()
HotkeyManager.Destroy() 'this will clear all your registered hotkeys as well as turn off the manager. 'or HotkeyManager.Disable() 'this will just turn the hotkey manager off, but still retain all your registered hotkeys for the next time you call Initialize()
<access modifier> Sub <function name>(ByVal <parameter name> As Object()) End Sub
Private Sub E_KeyPressed(ByVal params As Object()) End Sub
HotkeyManager.Initialize()
Dim my_key As Integer = CType(Keys.E, Integer) 'I will be using the "E" key as my hotkey.
Dim my_callback As HotkeyManager.HotkeyCallback = new HotkeyManager.HotkeyCallback(AddressOf E_KeyPressed) 'create a new Callback delegate.
Dim my_parameters As String() = {"this", "is", "an", "example"} 'these will be the parameters I pass to E_KeyPressed whenever it's called
HotkeyManager.RegisterHotkey(my_key, my_callback, my_parameters) 'now the hotkey is registered. Press 'E' and the function will be called.
Private Sub E_KeyPressed(ByVal params As Object())
For Each o As Object in params
Debug.WriteLine(o.ToString())
Next o
End Sub