允许全局热键
Allowing Global Hotkeys
首先,我不是一个真正的编码员,但我对我迄今为止所做的一切感到满意。
我在下面写了这段与机器人技术有关的代码。下面的代码允许我在您单击表单时使用键盘快捷键。但是,无论应用程序是否处于焦点或什至最小化,我都需要热键来工作。
网上已经看过了,不是很清楚。
Public Class MainForm
Private Sub MainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R)
End If
'If e.KeyCode = Keys.R Then
'DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R)
'End If
End Sub
Private Sub MainForm_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R)
End If
'If e.KeyCode = Keys.R Then
'DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R)
'End If
End Sub
Public Class MainForm
Private Sub MainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R)
End If
'If e.KeyCode = Keys.R Then
'DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R)
'End If
End Sub
Private Sub MainForm_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R)
End If
'If e.KeyCode = Keys.R Then
'DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R)
'End If
End Sub
End Class
更新:
没错。我现在添加了一个 class 以允许注册 GlobalKey。
在我的主窗体中,我现在有这个密钥:
Public Class MainForm
Dim hkr As New HotKeyRegistryClass(Me.Handle)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.A).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.S).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.D).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.F).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.G).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_SHIFT Or HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.H).ToString()
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE
Dim ID As String = m.WParam.ToString()
Select Case ID
Case 0 : If DF1Com1.Write("O:1/0", "1") Then DF1Com1.Write("O:1/0", "0")
Case 1 : MessageBox.Show("S")
Case 2 : MessageBox.Show("D")
Case 3 : MessageBox.Show("F")
Case 4 : MessageBox.Show("G")
Case 5 : MessageBox.Show("H")
End Select
End If
MyBase.WndProc(m)
End Sub
如果您查看 案例 0。它可以工作,但不会将密钥备份。它一直压低它。当按键按下时我需要它'DF1Com1.Write("O:1/0", "0")'
Class代码
Public NotInheritable Class HotKeyRegistryClass
Private Declare Function RegisterHotKey Lib "user32.dll" (ByVal handle As IntPtr, ByVal id As Int32, ByVal fsModifier As Int32, ByVal vk As Int32) As Int32
Private Declare Function UnregisterHotKey Lib "user32.dll" (ByVal handle As IntPtr, ByVal id As Int32) As Int32
Private Handle As IntPtr = IntPtr.Zero
Private Registry As New System.Collections.Generic.List(Of Int32)
Public Enum Messages
[WM_HOTKEY] = &H312
End Enum
Public Enum Modifiers
[MOD_ALT] = &H1
[MOD_CTRL] = &H2
[MOD_SHIFT] = &H4
End Enum
Sub New(ByVal Handle As IntPtr)
Me.Handle = Handle
End Sub
Public Function Register(ByVal Modifier As Int32, ByVal Key As System.Windows.Forms.Keys) As Int32
Dim ret As Int32
ret = NextAvailableIndex()
Call RegisterHotKey(Me.Handle, ret, Modifier, Key)
Registry.Insert(ret, ret)
Return ret
End Function
Public Sub Unregister(ByVal ID As Int32)
Call UnregisterHotKey(Me.Handle, ID)
Registry.Remove(ID)
End Sub
Private Function NextAvailableIndex() As Int32
Dim ret As Int32 = 0
Dim n As Int32 = 0
For i As Int32 = 0 To Registry.Count - 1
If Registry(i) = n Then
n = n + 1
ElseIf n < Registry(i) Then
Return n
End If
Next
If n = Registry.Count Then
Return Registry.Count
End If
Return ret
End Function
End Class
不幸的是,RegisterHotkey
仅在激活组合键时告诉您。此外,正如您已经意识到的那样,您拥有的 KeyDown
和 KeyUp
事件仅在您的应用获得焦点时才有效。
获得真正全局 KeyDown
和 KeyUp
的唯一方法是使用低级键盘挂钩。因为我不想复制我的整个答案,所以我会简单地 link 到它。 link 将为您提供一些设置键盘挂钩的指导。
另一种可能性是像这样在热键激活时执行两个命令...
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE
Dim ID As String = m.WParam.ToString()
Select Case ID
Case 0 :
DF1Com1.Write("O:1/0", "1")
System.Threading.Thread.Sleep(2000)
DF1Com1.Write("O:1/0", "0")
Case 1 : MessageBox.Show("S")
Case 2 : MessageBox.Show("D")
Case 3 : MessageBox.Show("F")
Case 4 : MessageBox.Show("G")
Case 5 : MessageBox.Show("H")
End Select
End If
MyBase.WndProc(m)
End Sub
实现此目的的另一种选择是使用布尔值进行跟踪。这样做意味着,按热键开始然后再按停止。
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Static toggle As Boolean
If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE
Dim ID As String = m.WParam.ToString()
Select Case ID
Case 0 :
If toggle Then
DF1Com1.Write("O:1/0", "0")
Else
DF1Com1.Write("O:1/0", "1")
End If
toggle = Not toggle
Case 1 : MessageBox.Show("S")
Case 2 : MessageBox.Show("D")
Case 3 : MessageBox.Show("F")
Case 4 : MessageBox.Show("G")
Case 5 : MessageBox.Show("H")
End Select
End If
MyBase.WndProc(m)
End Sub
首先,我不是一个真正的编码员,但我对我迄今为止所做的一切感到满意。
我在下面写了这段与机器人技术有关的代码。下面的代码允许我在您单击表单时使用键盘快捷键。但是,无论应用程序是否处于焦点或什至最小化,我都需要热键来工作。
网上已经看过了,不是很清楚。
Public Class MainForm
Private Sub MainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R)
End If
'If e.KeyCode = Keys.R Then
'DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R)
'End If
End Sub
Private Sub MainForm_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R)
End If
'If e.KeyCode = Keys.R Then
'DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R)
'End If
End Sub
Public Class MainForm
Private Sub MainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R)
End If
'If e.KeyCode = Keys.R Then
'DF1Com1.Write("O:1/0", "1") ' (O:9/0) (R)
'End If
End Sub
Private Sub MainForm_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R)
End If
'If e.KeyCode = Keys.R Then
'DF1Com1.Write("O:1/0", "0") ' (O:9/0) (R)
'End If
End Sub
End Class
更新:
没错。我现在添加了一个 class 以允许注册 GlobalKey。
在我的主窗体中,我现在有这个密钥:
Public Class MainForm
Dim hkr As New HotKeyRegistryClass(Me.Handle)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.A).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.S).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.D).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.F).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.G).ToString()
hkr.Register(HotKeyRegistryClass.Modifiers.MOD_SHIFT Or HotKeyRegistryClass.Modifiers.MOD_CTRL, Keys.H).ToString()
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE
Dim ID As String = m.WParam.ToString()
Select Case ID
Case 0 : If DF1Com1.Write("O:1/0", "1") Then DF1Com1.Write("O:1/0", "0")
Case 1 : MessageBox.Show("S")
Case 2 : MessageBox.Show("D")
Case 3 : MessageBox.Show("F")
Case 4 : MessageBox.Show("G")
Case 5 : MessageBox.Show("H")
End Select
End If
MyBase.WndProc(m)
End Sub
如果您查看 案例 0。它可以工作,但不会将密钥备份。它一直压低它。当按键按下时我需要它'DF1Com1.Write("O:1/0", "0")'
Class代码
Public NotInheritable Class HotKeyRegistryClass
Private Declare Function RegisterHotKey Lib "user32.dll" (ByVal handle As IntPtr, ByVal id As Int32, ByVal fsModifier As Int32, ByVal vk As Int32) As Int32
Private Declare Function UnregisterHotKey Lib "user32.dll" (ByVal handle As IntPtr, ByVal id As Int32) As Int32
Private Handle As IntPtr = IntPtr.Zero
Private Registry As New System.Collections.Generic.List(Of Int32)
Public Enum Messages
[WM_HOTKEY] = &H312
End Enum
Public Enum Modifiers
[MOD_ALT] = &H1
[MOD_CTRL] = &H2
[MOD_SHIFT] = &H4
End Enum
Sub New(ByVal Handle As IntPtr)
Me.Handle = Handle
End Sub
Public Function Register(ByVal Modifier As Int32, ByVal Key As System.Windows.Forms.Keys) As Int32
Dim ret As Int32
ret = NextAvailableIndex()
Call RegisterHotKey(Me.Handle, ret, Modifier, Key)
Registry.Insert(ret, ret)
Return ret
End Function
Public Sub Unregister(ByVal ID As Int32)
Call UnregisterHotKey(Me.Handle, ID)
Registry.Remove(ID)
End Sub
Private Function NextAvailableIndex() As Int32
Dim ret As Int32 = 0
Dim n As Int32 = 0
For i As Int32 = 0 To Registry.Count - 1
If Registry(i) = n Then
n = n + 1
ElseIf n < Registry(i) Then
Return n
End If
Next
If n = Registry.Count Then
Return Registry.Count
End If
Return ret
End Function
End Class
不幸的是,RegisterHotkey
仅在激活组合键时告诉您。此外,正如您已经意识到的那样,您拥有的 KeyDown
和 KeyUp
事件仅在您的应用获得焦点时才有效。
获得真正全局 KeyDown
和 KeyUp
的唯一方法是使用低级键盘挂钩。因为我不想复制我的整个答案,所以我会简单地 link 到它。 link 将为您提供一些设置键盘挂钩的指导。
另一种可能性是像这样在热键激活时执行两个命令...
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE
Dim ID As String = m.WParam.ToString()
Select Case ID
Case 0 :
DF1Com1.Write("O:1/0", "1")
System.Threading.Thread.Sleep(2000)
DF1Com1.Write("O:1/0", "0")
Case 1 : MessageBox.Show("S")
Case 2 : MessageBox.Show("D")
Case 3 : MessageBox.Show("F")
Case 4 : MessageBox.Show("G")
Case 5 : MessageBox.Show("H")
End Select
End If
MyBase.WndProc(m)
End Sub
实现此目的的另一种选择是使用布尔值进行跟踪。这样做意味着,按热键开始然后再按停止。
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Static toggle As Boolean
If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then 'NOT THE ACTUAL WINDOWS NAMESPACE
Dim ID As String = m.WParam.ToString()
Select Case ID
Case 0 :
If toggle Then
DF1Com1.Write("O:1/0", "0")
Else
DF1Com1.Write("O:1/0", "1")
End If
toggle = Not toggle
Case 1 : MessageBox.Show("S")
Case 2 : MessageBox.Show("D")
Case 3 : MessageBox.Show("F")
Case 4 : MessageBox.Show("G")
Case 5 : MessageBox.Show("H")
End Select
End If
MyBase.WndProc(m)
End Sub