Last active
October 1, 2023 07:28
-
-
Save KOZ60/ecba5a99c123410d983980c6239d4ea0 to your computer and use it in GitHub Desktop.
Hotkey.vb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Imports System.Collections | |
Imports System.Collections.Generic | |
Imports System.ComponentModel | |
Imports System.Runtime.InteropServices | |
Imports System.Windows.Forms | |
<DefaultEvent("HotkeyPress")> | |
Public Class Hotkey | |
Inherits Component | |
Private Shared countId As Integer | |
Private ReadOnly catcher As InternalControl | |
Private ReadOnly entries As EntryCollcetion | |
Public Sub New() | |
catcher = New InternalControl(Me) | |
entries = New EntryCollcetion | |
End Sub | |
Public Sub New(container As IContainer) | |
Me.New() | |
If container Is Nothing Then | |
Throw New ArgumentNullException("container") | |
End If | |
container.Add(Me) | |
End Sub | |
Public Function Register(keys As Keys, modifiers As Modifiers) As Boolean | |
Dim entry As Entry = Nothing | |
If entries.TryGetValue(keys, modifiers, entry) Then | |
Return True | |
End If | |
If RegisterHotKey(catcher.Handle, countId, modifiers, keys) Then | |
entry = New Entry(countId, keys, modifiers) | |
entries.Add(entry) | |
countId += 1 | |
Return True | |
Else | |
Return False | |
End If | |
End Function | |
Public Function UnRegister(keys As Keys, modifiers As Modifiers) As Boolean | |
Dim entry As Entry = Nothing | |
If Not entries.TryGetValue(keys, modifiers, entry) Then | |
Return False | |
End If | |
entries.Remove(entry) | |
Return UnregisterHotKey(catcher.Handle, entry.Id) | |
End Function | |
Private Sub OnHotkeyPressCaller(wParam As IntPtr) | |
Dim id = wParam.ToInt32() | |
Dim entry As Entry = Nothing | |
If entries.TryGetValue(id, entry) Then | |
OnHotkeyPress(entry) | |
End If | |
End Sub | |
Protected Overridable Sub OnHotkeyPress(e As HotkeyEventArgs) | |
If CanRaiseEvents Then | |
RaiseEvent HotkeyPress(Me, e) | |
End If | |
End Sub | |
Public Event HotkeyPress As EventHandler(Of HotkeyEventArgs) | |
<Flags> | |
Public Enum Modifiers | |
None = 0 | |
Alt = &H1 | |
Control = &H2 | |
Shift = &H4 | |
Winkey = &H8 | |
End Enum | |
Public Class HotkeyEventArgs | |
Inherits EventArgs | |
Public ReadOnly Property Keys As Keys | |
Public ReadOnly Property Modifiers As Modifiers | |
Public Sub New(keys As Keys, modifiers As Modifiers) | |
Me.Keys = keys | |
Me.Modifiers = modifiers | |
End Sub | |
Public Overrides Function ToString() As String | |
Return $"{Modifiers} + {Keys}" | |
End Function | |
End Class | |
Private Class Entry | |
Inherits HotkeyEventArgs | |
Public ReadOnly Property Id As Integer | |
Public Sub New(id As Integer, keys As Keys, modifiers As Modifiers) | |
MyBase.New(keys, modifiers) | |
Me.Id = id | |
End Sub | |
End Class | |
Private Class EntryCollcetion | |
Implements IEnumerable(Of Entry) | |
Private ReadOnly dicKey As New Dictionary(Of Tuple(Of Keys, Modifiers), Entry) | |
Private ReadOnly dicId As New Dictionary(Of Integer, Entry) | |
Public Sub Clear() | |
dicKey.Clear() | |
dicId.Clear() | |
End Sub | |
Public Function TryGetValue(id As Integer, ByRef entry As Entry) As Boolean | |
Return dicId.TryGetValue(id, entry) | |
End Function | |
Public Function TryGetValue(keys As Keys, modifiers As Modifiers, ByRef entry As Entry) As Boolean | |
Dim key = CreateKey(keys, modifiers) | |
Return dicKey.TryGetValue(key, entry) | |
End Function | |
Public Sub Add(ent As Entry) | |
Dim key = CreateKey(ent.Keys, ent.Modifiers) | |
dicKey.Add(key, ent) | |
dicId.Add(ent.Id, ent) | |
End Sub | |
Public Sub Remove(ent As Entry) | |
Dim key = CreateKey(ent.Keys, ent.Modifiers) | |
dicKey.Remove(key) | |
dicId.Remove(ent.Id) | |
End Sub | |
Private Shared Function CreateKey(keys As Keys, modifiers As Modifiers) As Tuple(Of Keys, Modifiers) | |
Return New Tuple(Of Keys, Modifiers)(keys, modifiers) | |
End Function | |
Public Iterator Function GetEnumerator() As IEnumerator(Of Entry) Implements IEnumerable(Of Entry).GetEnumerator | |
For Each kp In dicKey | |
Yield kp.Value | |
Next | |
End Function | |
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator | |
Return GetEnumerator() | |
End Function | |
End Class | |
Private Const WM_HOTKEY As Integer = &H312 | |
Private Class InternalControl | |
Inherits Control | |
Private ReadOnly Owner As Hotkey | |
Public Sub New(owner As Hotkey) | |
Me.Owner = owner | |
End Sub | |
Protected Overrides Sub WndProc(ByRef m As Message) | |
If m.Msg = WM_HOTKEY Then | |
Owner.OnHotkeyPressCaller(m.WParam) | |
Else | |
MyBase.WndProc(m) | |
End If | |
End Sub | |
End Class | |
<DllImport("user32", CharSet:=CharSet.Auto)> | |
Private Shared Function RegisterHotKey( | |
hwnd As IntPtr, id As Integer, | |
fsModifiers As Modifiers, vk As Keys) As Boolean | |
End Function | |
<DllImport("user32", CharSet:=CharSet.Auto)> | |
Private Shared Function UnregisterHotKey(hwnd As IntPtr, id As Integer) As Boolean | |
End Function | |
Private disposedValue As Boolean | |
Protected Overrides Sub Dispose(disposing As Boolean) | |
If Not disposedValue Then | |
disposedValue = True | |
If disposing Then | |
For Each entry In entries | |
UnregisterHotKey(catcher.Handle, entry.Id) | |
Next | |
entries.Clear() | |
catcher.Dispose() | |
End If | |
End If | |
MyBase.Dispose(disposing) | |
End Sub | |
End Class |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to use:
Paste it on form.