none
How to Detecting Keypress While the form is Minimized ? RRS feed

  • Question

  • hello everyone,

    I would like to make my application listen for a key when the application is not focused

    I'm using this code but it's working only when the form is focused

      Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
            If e.KeyCode = Keys.T AndAlso e.Control = True Then
               Form2.show
            End If
        End Sub
    thanks in advance


    Thursday, September 12, 2019 2:02 PM

Answers

  • Hi

    Here is your code which works to reset the Minimized Form to'Normal' state. (I was unsure of your use of Me.Show)

    Option Strict On
    Option Explicit On
    Imports System.Runtime.InteropServices
    Public Class Form1
    
    	<DllImport("User32", CharSet:=CharSet.Auto, SetLastError:=True)>
    	Public Shared Function RegisterHotKey(hWnd As IntPtr, id As Integer, fsModifiers As Integer, vk As Integer) As Boolean
    	End Function
    
    	<DllImport("User32", CharSet:=CharSet.Auto, SetLastError:=True)>
    	Public Shared Function UnregisterHotKey(hWnd As IntPtr, id As Integer) As Boolean
    	End Function
    
    	<DllImport("Kernel32", CharSet:=CharSet.Unicode, SetLastError:=True)>
    	Public Shared Function GlobalAddAtom(atomName As String) As Short
    	End Function
    
    	''--- Pinvoke:
    	Public Const MOD_ALT As Integer = &H1
    	Public Const MOD_CONTROL As Integer = &H2
    	Public Const MOD_SHIFT As Integer = &H4
    	Public Const MOD_WIN As Integer = &H8
    	Public Const MOD_NOREPEAT As Integer = &H4000
    	Public Const WM_HOTKEY As Integer = &H312
    
    
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
    		RegisterHotKey(Me.Handle, 100, MOD_CONTROL or MOD_SHIFT, Keys.D)
    		RegisterHotKey(Me.Handle, 200, MOD_ALT, Keys.S)
    	End Sub
    
    
    	Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    		UnregisterHotKey(Me.Handle, 100)
    	End Sub
    
    	Protected Overrides Sub WndProc(ByRef m As Message)
    		If m.Msg = WM_HOTKEY Then
    			Dim ID As String = m.WParam.ToString()
    			Select Case (ID.ToString)
    				Case "100"
    					Me.WindowState = FormWindowState.Normal
    				Case "200"
    					MsgBox("200")
    			End Select
    		End If
    		MyBase.WndProc(m)
    	End Sub
    End Class


    Regards Les, Livingston, Scotland



    • Marked as answer by Mostafa Salaheldien Thursday, September 12, 2019 6:12 PM
    • Edited by leshay Thursday, September 12, 2019 6:14 PM
    Thursday, September 12, 2019 6:05 PM

All replies

  • One of the ways is with RegisterHotKey

        <DllImport("User32", CharSet:=CharSet.Auto, SetLastError:=True)>
        Public Shared Function RegisterHotKey(hWnd As IntPtr, id As Integer, fsModifiers As Integer, vk As Integer) As Boolean
        End Function
        
        <DllImport("User32", CharSet:=CharSet.Auto, SetLastError:=True)>
        Public Shared Function UnregisterHotKey(hWnd As IntPtr, id As Integer) As Boolean
        End Function
        
        <DllImport("Kernel32", CharSet:=CharSet.Unicode, SetLastError:=True)>
        Public Shared Function GlobalAddAtom(atomName As String) As Short
        End Function
        
        Public Const MOD_ALT = &H1
        Public Const MOD_CONTROL = &H2
        Public Const MOD_SHIFT = &H4
        Public Const MOD_WIN = &H8
        Public Const MOD_NOREPEAT = &H4000
    
        Public Const WM_HOTKEY = &H312

    Thursday, September 12, 2019 2:19 PM
  • Hi

    Here is my example (Castorix example is much more compact)

    My example uses Form1 with CheckBox1 and CheckBox2 (both at default unchecked state), and has a Class called HotKeys also.

    The example uses the two checkboxes to set whether or not to use HotKeys at all, and whether to use only when Form1 is Minimized.

    I have set up 2 hotkeys for this example (T and Q)

    Form1

    Option Strict On Option Explicit On Public Class Form1 Dim hooked As New HotKeyRegistryClass(Me.Handle) Dim UseHotkeys As Boolean = False Dim MinimizedOnly As Boolean = False Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing hooked.Unregister(0)

            hooked.Unregister(1) End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load hooked.Register(HotKeyRegistryClass.Modifiers.MOD_NONE, Keys.T).ToString() ' and as many other HotKeys needed hooked.Register(HotKeyRegistryClass.Modifiers.MOD_NONE, Keys.Q).ToString() UseHotkeys = CheckBox1.Checked End Sub Protected Overrides Sub WndProc(ByRef m As Message) If UseHotkeys Then If MinimizedOnly Then If Me.WindowState = FormWindowState.Minimized Then HK(m) End If Else HK(m) End If End If MyBase.WndProc(m) End Sub Sub HK(m As Message) If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then Dim ID As String = m.WParam.ToString() Select Case ID Case "0" MessageBox.Show("HotKey T pressed") Case "1" MessageBox.Show("HotKey Q pressed") End Select End If End Sub Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged, CheckBox2.CheckedChanged Dim cb As CheckBox = CType(sender, CheckBox) Select Case cb.Name Case "CheckBox1" UseHotkeys = cb.Checked Case "CheckBox2" MinimizedOnly = cb.Checked End Select End Sub End Class

    Class HotKeys

    ' code by DavesChillaxin from post at
    ' http://www.vbforums.com/showthread.php?672702-Register-Global-HotKeys
    
    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 List(Of Integer)
    
    	Public Enum Messages
    		[WM_HOTKEY] = &H312
    	End Enum
    	Public Enum Modifiers
    		[MOD_NONE] = &H0
    		[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 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


    Regards Les, Livingston, Scotland


    • Edited by leshay Thursday, September 12, 2019 3:06 PM
    Thursday, September 12, 2019 3:04 PM
  • Thank You so much its worked but i have one more question please

    this is my code now

    <DllImport("User32", CharSet:=CharSet.Auto, SetLastError:=True)> Public Shared Function RegisterHotKey(hWnd As IntPtr, id As Integer, fsModifiers As Integer, vk As Integer) As Boolean End Function <DllImport("User32", CharSet:=CharSet.Auto, SetLastError:=True)> Public Shared Function UnregisterHotKey(hWnd As IntPtr, id As Integer) As Boolean End Function <DllImport("Kernel32", CharSet:=CharSet.Unicode, SetLastError:=True)> Public Shared Function GlobalAddAtom(atomName As String) As Short End Function ''--- Pinvoke: Public Const MOD_ALT = &H1 Public Const MOD_CONTROL = &H2 Public Const MOD_SHIFT = &H4 Public Const MOD_WIN = &H8 Public Const MOD_NOREPEAT = &H4000 Public Const WM_HOTKEY = &H312 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load RegisterHotKey(Me.Handle, 100, MOD_CONTROL, MOD_SHIFT, Keys.D) RegisterHotKey(Me.Handle, 200, MOD_ALT, Keys.S) End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing  
            UnregisterHotKey(Me.Handle, 100)  
        End Sub Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) If m.Msg = WM_HOTKEY Then Dim id As IntPtr = m.WParam Select Case (id.ToString) Case "100" Me.Show() Case "200" MsgBox("200") End Select End If MyBase.WndProc(m) End Sub


    in this line

            RegisterHotKey(Me.Handle, 100, MOD_CONTROL, MOD_SHIFT, Keys.D)

    i want if the user press ctrl + shift + d

    but its shown error

    Severity	Code	Description	Project	File	Line	Suppression State
    Error	BC30057	Too many arguments to 'Public Shared Function RegisterHotKey(hWnd As IntPtr, id As Integer, fsModifiers As Integer, vk As Integer) As Boolean'.	WindowsApplication20	C:\Users\Mostafa\Documents\Visual Studio 2015\Projects\WindowsApplication20\WindowsApplication20\Form1.vb	27	Active
    
    Thank you




    Thursday, September 12, 2019 4:48 PM
  • Hi

    Here is your code which works to reset the Minimized Form to'Normal' state. (I was unsure of your use of Me.Show)

    Option Strict On
    Option Explicit On
    Imports System.Runtime.InteropServices
    Public Class Form1
    
    	<DllImport("User32", CharSet:=CharSet.Auto, SetLastError:=True)>
    	Public Shared Function RegisterHotKey(hWnd As IntPtr, id As Integer, fsModifiers As Integer, vk As Integer) As Boolean
    	End Function
    
    	<DllImport("User32", CharSet:=CharSet.Auto, SetLastError:=True)>
    	Public Shared Function UnregisterHotKey(hWnd As IntPtr, id As Integer) As Boolean
    	End Function
    
    	<DllImport("Kernel32", CharSet:=CharSet.Unicode, SetLastError:=True)>
    	Public Shared Function GlobalAddAtom(atomName As String) As Short
    	End Function
    
    	''--- Pinvoke:
    	Public Const MOD_ALT As Integer = &H1
    	Public Const MOD_CONTROL As Integer = &H2
    	Public Const MOD_SHIFT As Integer = &H4
    	Public Const MOD_WIN As Integer = &H8
    	Public Const MOD_NOREPEAT As Integer = &H4000
    	Public Const WM_HOTKEY As Integer = &H312
    
    
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
    		RegisterHotKey(Me.Handle, 100, MOD_CONTROL or MOD_SHIFT, Keys.D)
    		RegisterHotKey(Me.Handle, 200, MOD_ALT, Keys.S)
    	End Sub
    
    
    	Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    		UnregisterHotKey(Me.Handle, 100)
    	End Sub
    
    	Protected Overrides Sub WndProc(ByRef m As Message)
    		If m.Msg = WM_HOTKEY Then
    			Dim ID As String = m.WParam.ToString()
    			Select Case (ID.ToString)
    				Case "100"
    					Me.WindowState = FormWindowState.Normal
    				Case "200"
    					MsgBox("200")
    			End Select
    		End If
    		MyBase.WndProc(m)
    	End Sub
    End Class


    Regards Les, Livingston, Scotland



    • Marked as answer by Mostafa Salaheldien Thursday, September 12, 2019 6:12 PM
    • Edited by leshay Thursday, September 12, 2019 6:14 PM
    Thursday, September 12, 2019 6:05 PM
  • Thank you so much  It's perfect
    Thursday, September 12, 2019 6:12 PM
  • Hi

    Castorix post should be the one for Answered, I only provided a small modification.

    I also modified my post - I replaced the '+' with an 'Or' - much better.

    Don't forget to UnRegister ALL the registered hotkeys when application closed.

    *

    Here is partial modified code to list hotkeys registered and a loop to unregister.

    	Dim rhk As New List(Of Integer)
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    		Dim r As Boolean = False
    		If RegisterHotKey(Me.Handle, 100, MOD_CONTROL Or MOD_SHIFT, Keys.D) Then rhk.Add(100)
    		If RegisterHotKey(Me.Handle, 200, MOD_ALT, Keys.D) Then rhk.Add(200)
    	End Sub
    	Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    		For Each i As Integer In rhk
    			UnregisterHotKey(Me.Handle, i)
    		Next
    	End Sub


    Regards Les, Livingston, Scotland


    • Edited by leshay Thursday, September 12, 2019 6:25 PM
    Thursday, September 12, 2019 6:17 PM
  • Thank u so much
    Monday, January 20, 2020 12:31 PM