简体   繁体   中英

How to detect Ctrl+Alt+H using Low level Keyboard Hook?

I am writing a function to hide/show my application and I want to use a shortcut combination of Ctrl+Alt+H for hiding and showing the form.

This is my code so far:

Imports System.Runtime.InteropServices
''' <summary>
''' Global Keyboard Hook
''' </summary>
''' <remarks>This is the keyboard hook class which will carry out the process to identify which keystroke is pressed. </remarks>
Public Class GlobalKeyboardHook
    Private Const HC_ACTION As Integer = 0
    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const WM_KEYDOWN As Integer = &H100
    Private Const WM_KEYUP As Integer = &H101
    Private Const WM_SYSKEYDOWN As Integer = &H104
    Private Const WM_SYSKEYUP As Integer = &H105
    Private Structure Hook_Structure
        Public VK_Code As Integer
        Public Scan_Code As Integer
        Public _Flags As Integer
        Public _Time As Integer
        Public DW_Extra_Info As Integer
    End Structure
    Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal ID_Hook As Integer, ByVal LP_FN As Key_ProcessDelegate, ByVal H_Mod As Integer, ByVal DW_Thread_ID As Integer) As Integer
    Private Declare Function CallNextHookEx Lib "user32" (ByVal H_Hook As Integer, ByVal N_Code As Integer, ByVal W_Param As Integer, ByVal L_Param As Hook_Structure) As Integer
    Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal H_Hook As Integer) As Integer
    Private Delegate Function Key_ProcessDelegate(ByVal N_Code As Integer, ByVal W_Param As Integer, ByRef L_Param As Hook_Structure) As Integer
    Public Shared Event KeyDown(ByVal Key As Keys)
    Public Shared Event KeyUp(ByVal Key As Keys)
    Private Shared KeyHook As Integer
    Private Shared KeyHookDelegate As Key_ProcessDelegate
    Public Sub Hook()
        KeyHookDelegate = New Key_ProcessDelegate(AddressOf Key_Process)
        KeyHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyHookDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
    End Sub
    Private Function Key_Process(ByVal N_Code As Integer, ByVal W_Param As Integer, ByRef L_Param As Hook_Structure) As Integer
        If (N_Code = HC_ACTION) Then
            Select Case W_Param
                Case WM_KEYDOWN, WM_SYSKEYDOWN
                    RaiseEvent KeyDown(CType(L_Param.VK_Code, Keys))
                Case WM_KEYUP, WM_SYSKEYUP
                    RaiseEvent KeyUp(CType(L_Param.VK_Code, Keys))
            End Select
        End If
        Return CallNextHookEx(KeyHook, N_Code, W_Param, L_Param)
    End Function
    Public Sub Unhook()
        UnhookWindowsHookEx(KeyHook)
        MyBase.Finalize()
    End Sub
    Public Function Feed(ByVal e As Keys) As String
        Return e.ToString
    End Function
End Class

And inside the Form1 Class:

Private WithEvents KeyHook As New GlobalKeyboardHook
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            KeyHook.Hook()
    End Sub
    Private Sub KeyPress_Event(ByVal e As Keys) Handles KeyHook.KeyDown
            If Control.ModifierKeys = Keys.Alt Then 'Or Control.ModifierKeys = Keys.Ctrl
                If KeyHook.Feed(e) = "H" Then
                    'Show Form/Hide Form
                End If
            End If
End Sub

This code works fine for me if I use one of the modifier keys Alt, Ctrl, Shift etc., But as I want to use two modifier keys ie, ALT and Ctrl and then H key, I am trying with the logic:

Private Sub KeyPress_Event(ByVal e As Keys) Handles KeyHook.KeyDown
            If Control.ModifierKeys = Keys.Alt AndAlso Control.ModifierKeys = Keys.Ctrl Then
                If KeyHook.Feed(e) = "H" Then
                    'Show Form/Hide Form
                End If
            End If
End Sub

But I understood that it is not the right approach. What is the correct logic here?

I just used My.Computer class.

Private Sub KeyRelease_Event(ByVal e As Keys) Handles KeyHook.KeyDown
        If My.Computer.Keyboard.AltKeyDown AndAlso My.Computer.Keyboard.CtrlKeyDown Then
            If KeyHook.Feed(e) <> Nothing Then
                'Show Form/Hide Form
            End If
        End If
    End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM