.NET 系统范围热键组件






4.33/5 (21投票s)
一个用于响应系统范围热键组合的组件。
引言
系统范围的热键是一种按键组合,无论哪个应用程序具有输入焦点,都会触发特定事件。 例如,如果您按下 WIN+E,则会启动一个新的资源管理器实例,或者如果您按下 CTRL+PRINTSCREEN,则当前活动的窗口会被屏幕截图到剪贴板。
Win32 API 有几个调用用于设置和响应热键 - 特别是 RegisterHotKey
和 UnregisterHotKey
,您可以在 VB.NET 中这样声明
<DllImport("user32", EntryPoint:="RegisterHotKey", _
SetLastError:=True, _
ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Public Function RegisterHotkey(ByVal hwnd As IntPtr, _
ByVal Id As Int32, _
<MarshalAs(UnmanagedType.U4)> ByVal fsModifiers As Int32, _
<MarshalAs(UnmanagedType.U4)> ByVal vkey As Int32) As Boolean
End Function
<DllImport("user32", EntryPoint:="UnregisterHotKey", _
SetLastError:=True, _
ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Public Function UnregisterHotkey(ByVal hwnd As Int32, _
ByVal Id As Int32) As Boolean
End Function
在热键通过 API 调用 RegisterHotkey
注册后,每当按下指定的按键组合时,就会将 WM_HOTKEY
Windows 消息发送到 hwnd
参数中传递给它的窗口。
指定按键组合
触发事件的键由两个参数 fsModifiers
和 vKey
定义。
fsModifiers
是一个值,它告诉操作系统,热键组合中包含哪些修饰键 - 即 Alt、Ctrl、Shift 或 Win 键。 这个值由以下标志的组合组成
Public Enum HotkeyModifierFlags
MOD_ALT = &H1
MOD_CONTROL = &H2
MOD_SHIFT = &H4
MOD_WIN = &H8
End Enum
因此,例如,如果您想要一个热键是 CTRL+ALT+C,那么修饰符将是 MOD_ALT
+ MOD_CONTROL
。
vKey
参数是与修饰符一起定义热键组合的键的虚拟键代码。
指定唯一的热键 ID
id
参数用于区分给定窗口可以接收的多个热键。 为了确保我们处理的是唯一的 ID,我使用 API 调用 GlobalAddAtom
来返回 id
。 这是这样声明的
<DllImport("kernel32", EntryPoint:="GlobalAddAtom", _
SetLastError:=True, _
ExactSpelling:=False)> _
Public Function GlobalAddAtom(<MarshalAs(UnmanagedType.LPTStr)> _
ByVal lpString As String) As Int32
End Function
创建一个窗口来监听 WM_HOTKEY 消息
最后一个参数是一个窗口句柄,用于监听 WM_HOTKEY
消息。 在这里有两个选择 - 要么传入现有窗口的句柄并子类化它的 WndProc
以查找该消息,要么创建一个新的不可见窗口专门用于监听该消息。
第二种选择是通过创建一个派生自 System.Windows.Forms.NativeWindow
的新类来实现的,如下所示
Public Class GlobalHotkeyListener
Inherits NativeWindow
#Region "Private member variables"
Private windowHandle As Integer
Private mwh As ManualResetEvent
#End Region
Public Sub New(ByVal Id As Int32, _
ByVal fsModifiers As Int32, _
ByVal vkey As Int32, _
ByRef wh As ManualResetEvent)
'\\ Get a local copy of the wait handle
mwh = wh
Dim cp As CreateParams = New CreateParams()
' Fill in the CreateParams details.
cp.Caption = ""
cp.ClassName = "STATIC"
' Set the position on the form
cp.X = 0
cp.Y = 0
cp.Height = 0
cp.Width = 0
'\\ Set the style and extended style flags
cp.Style = WindowStyleBits.WS_MINIMIZE
cp.ExStyle = WindowStyleExtendedBits.WS_EX_NOACTIVATE
' Create the actual window
Me.CreateHandle(cp)
Try
If Not RegisterHotkey(MyBase.Handle, _
Id, fsModifiers, vkey) Then
Throw New Win32Exception()
End If
Catch e As Exception
System.Diagnostics.Debug.WriteLine(e.ToString)
End Try
End Sub
对 WM_HOTKEY
的监听是这样完成的
<System.Security.Permissions._
PermissionSetAttribute(System.Security.Permissions_
.SecurityAction.Demand, Name:="FullTrust")> _
Protected Overrides Sub WndProc(ByRef m As Message)
' Listen for messages that are sent to the
' button window. Some messages are sent
' to the parent window instead of the button's window.
Select Case (m.Msg)
Case WM_HOTKEY
' Respond to the hotkey message (asynchronously??)
If Not mwh Is Nothing Then
mwh.Set()
End If
End Select
MyBase.WndProc(m)
End Sub
未来改进
理想情况下,这个控件应该有一个 UIEditor
派生的类,以允许选择按键组合。