UPDATE: New updates have been made for ease of use and implementation in any project. Attached is a new working example.
Here's a class which gives you the ability to add hotkeys globally! This means regardless the forms focus state, your hotkeys guaranteed to fire. Note: Hotkeys can be overwritten if you will by other applications. If you register Ctrl+A, then afterwards a game does too. The game now has that hotkey and yours will no longer fire.
Class
vbnet Code:
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
To unregister the hotkey's pass that same Form1.Handle and the hk you're going to unregister to the HotKeyRegistry.UnregisterGlobalHotKey method
Make sure you place the last bit of code I provided in my original post in the forms code you plan on using to catch these key presses with.
Hope this helps.. and I'm sure my name spaces didn't help at all. Enjoy!
EDIT: Honestly having only worked in a professional setting for 2 months, have I noticed I would change sooo much with what I have here.. Perhaps I'll do an update in a few, haven't been doing much at home now that I code 5 days a week, 8 hours a day.
Last edited by DavesChillaxin; Apr 18th, 2012 at 10:23 PM.
Please rate if my post was helpful!
Per favore e grazie!
Thank you for the updates
I am trying to get familar with .Net for work as I do little things here and there to automate or make things simpler.
Everything works as advertised and the example you posted is awesome.
What if I wanted to have multiple modifiers [ctrl],[shift],A?
Looks like in your revision you removed this ability.
Per your first explaination:
Dim HotKeyRegistry As New HotKeyRegistryClass(Me.Handle)
Dim hk2 As New Collections.Items.HotKey(2, Windows.Keys.MOD_CTRL Or Windows.Keys.MOD_ALT, Keys.A)
Collections.Items.HotKey is not defined.
Last edited by maramor; Apr 19th, 2012 at 08:46 AM.
Your welcome, and im glad it all worked without a hitch. The multiple modifiers still works. My new example never demonstrated but its just as it was before. To do for example, alt+ctrl. When registering a hotkey pass Modifier.MOD_ALT Or Modifier.MOD_CTRL. Technically you are passing &H1 Or &H2.. I believe are the corresponding values.
I know you can do all three, just pass whatever modifier you want and an Or operator in between each modifier you want.
[MOD] Or [MOD2] Or [MOD3] ...
Please rate if my post was helpful!
Per favore e grazie!
I do believe you can pass 0. If anything or &H0, i haven't tried. But if you cant figure it out by the time im out of work i will look into that for you.
Simple mistake, I only know to use Or because that's just what I've always seen since i first began coding with vb6. My guess is its because they are requiring logical disjunction comparisons, which Or is. Where as And is a logical conjunction. I could be wrong but to be honest i haven't seen much documentation on exactly why you use Or for flag concatenations.
Please rate if my post was helpful!
Per favore e grazie!
Now that I kinda understand how it works I am going to try and build a nice little pick your HotKey's menu for my app and see if I can store it in "My.Settings". Yahoo!!
Again, thank you for the post, responses and assistance.
Would you happen to know how I would do something like this?
Dim KK As Keys = CType(TextBox1.Text, Keys)
or perhaps I am thinking wrong.
Basically I have a form that allows me to set the MOD keys and define the basic key. My challenge now is since I have TextBox1.Text with a Keys value I need to convert it to a KEYS object inorder to fit in the register command.
Code:
hkr.Unregister(0)
Dim P1 As Integer
Dim P2 As Integer
Dim P3 As Integer
Dim P4 As Integer
Dim KK As Keys = CType(TextBox1.Text, Keys)
If Label3.Text = "{CTRL}" Then
P1 = HotKeyRegistryClass.Modifiers.MOD_CTRL
ElseIf Label3.Text = "{ALT}" Then
P1 = HotKeyRegistryClass.Modifiers.MOD_ALT
ElseIf Label3.Text = "{SHIFT}" Then
P1 = HotKeyRegistryClass.Modifiers.MOD_SHIFT
ElseIf Label3.Text = "{WIN}" Then
P1 = HotKeyRegistryClass.Modifiers.MOD_WIN
End If
If Label4.Text = "{CTRL}" Then
P2 = HotKeyRegistryClass.Modifiers.MOD_CTRL
ElseIf Label4.Text = "{ALT}" Then
P2 = HotKeyRegistryClass.Modifiers.MOD_ALT
ElseIf Label4.Text = "{SHIFT}" Then
P2 = HotKeyRegistryClass.Modifiers.MOD_SHIFT
ElseIf Label4.Text = "{WIN}" Then
P2 = HotKeyRegistryClass.Modifiers.MOD_WIN
End If
If Label5.Text = "{CTRL}" Then
P3 = HotKeyRegistryClass.Modifiers.MOD_CTRL
ElseIf Label5.Text = "{ALT}" Then
P3 = HotKeyRegistryClass.Modifiers.MOD_ALT
ElseIf Label5.Text = "{SHIFT}" Then
P3 = HotKeyRegistryClass.Modifiers.MOD_SHIFT
ElseIf Label5.Text = "{WIN}" Then
P3 = HotKeyRegistryClass.Modifiers.MOD_WIN
End If
If Label6.Text = "{CTRL}" Then
P4 = HotKeyRegistryClass.Modifiers.MOD_CTRL
ElseIf Label6.Text = "{ALT}" Then
P4 = HotKeyRegistryClass.Modifiers.MOD_ALT
ElseIf Label6.Text = "{SHIFT}" Then
P4 = HotKeyRegistryClass.Modifiers.MOD_SHIFT
ElseIf Label6.Text = "{WIN}" Then
P4 = HotKeyRegistryClass.Modifiers.MOD_WIN
End If
hkr.Register(P1 Or P2 Or P3 Or P4, KK)
Thank you. It works! Although I get a implicit conversion warning when Strict is on, I just removed that and it works.
Here is my code thus far for my menu with only one issue with saving the key value to MySettings, msgboxes show the correct key but after close and repopen it is blank. At least anyone else stumbling across this article can see another example. I think the combination of my menu (once fully working) and your code makes a nice addition to any project . Thank you for all your help.
Code:
Public Class HotKeyz
Dim x As String
Dim hkr As New HotKeyRegistryClass(Me.Handle)
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 Convert.ToString(0) : Clipboard.SetDataObject(TimeStamp.TextBox1.Text + " " + TimeStamp.Label1.Text + " " + TimeStamp.Label2.Text + vbCrLf + vbCrLf) 'MessageBox.Show("F")
'Case 0 : MessageBox.Show("F")
End Select
End If
MyBase.WndProc(m)
End Sub
Private Sub HotKeyz_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Leave
End Sub
Private Sub HotKeyz_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If My.Settings.HK_CTRL = 1 Then
HotKeyz("CTRL", 1)
ElseIf My.Settings.HK_CTRL <= 0 Then
HotKeyz("CTRL", 0)
End If
If My.Settings.HK_ALT = 1 Then
HotKeyz("ALT", 1)
ElseIf My.Settings.HK_ALT <= 0 Then
HotKeyz("ALT", 0)
End If
If My.Settings.HK_SHIFT = 1 Then
HotKeyz("SHIFT", 1)
ElseIf My.Settings.HK_SHIFT <= 0 Then
HotKeyz("SHIFT", 0)
End If
If My.Settings.HK_WIN = 1 Then
HotKeyz("WIN", 1)
ElseIf My.Settings.HK_WIN <= 0 Then
HotKeyz("WIN", 0)
End If
MsgBox("CTRL = " + My.Settings.HK_CTRL.ToString + vbCrLf + _
"ALT = " + My.Settings.HK_ALT.ToString + vbCrLf + _
"SHIFT = " + My.Settings.HK_SHIFT.ToString + vbCrLf + _
"WIN = " + My.Settings.HK_WIN.ToString + vbCrLf + _
"KEY = " + My.Settings.HotKeyzKEY)
If Label3.Text = "" Then
Label2.Text = TextBox1.Text
Else
Label2.Text = Label3.Text + Label4.Text + Label5.Text + Label6.Text + " + " + TextBox1.Text
End If
End Sub
Public Sub HotKeyz(ByVal MODz As String, ByVal Status As Integer)
If MODz = "CTRL" And Status = 1 Then
If Label3.Text = "" Then
Label3.Text = "{CTRL}"
ElseIf Label4.Text = "" Then
Label4.Text = "{CTRL}"
ElseIf Label5.Text = "" Then
Label5.Text = "{CTRL}"
ElseIf Label6.Text = "" Then
Label6.Text = "{CTRL}"
End If
My.Settings.HK_CTRL = 1
Button1.FlatStyle = FlatStyle.Flat
ElseIf MODz = "CTRL" And Status = 0 Then
If Label3.Text = "{CTRL}" Then
Label3.Text = Label4.Text
Label4.Text = Label5.Text
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label4.Text = "{CTRL}" Then
Label4.Text = Label5.Text
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label5.Text = "{CTRL}" Then
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label6.Text = "{CTRL}" Then
Label6.Text = ""
End If
My.Settings.HK_CTRL = 0
Button1.FlatStyle = FlatStyle.Standard
End If
If MODz = "ALT" And Status = 1 Then
If Label3.Text = "" Then
Label3.Text = "{ALT}"
ElseIf Label4.Text = "" Then
Label4.Text = "{ALT}"
ElseIf Label5.Text = "" Then
Label5.Text = "{ALT}"
ElseIf Label6.Text = "" Then
Label6.Text = "{ALT}"
End If
My.Settings.HK_ALT = 1
Button2.FlatStyle = FlatStyle.Flat
ElseIf MODz = "ALT" And Status = 0 Then
If Label3.Text = "{ALT}" Then
Label3.Text = Label4.Text
Label4.Text = Label5.Text
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label4.Text = "{ALT}" Then
Label4.Text = Label5.Text
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label5.Text = "{ALT}" Then
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label6.Text = "{ALT}" Then
Label6.Text = ""
End If
My.Settings.HK_ALT = 0
Button2.FlatStyle = FlatStyle.Standard
End If
If MODz = "SHIFT" And Status = 1 Then
If Label3.Text = "" Then
Label3.Text = "{SHIFT}"
ElseIf Label4.Text = "" Then
Label4.Text = "{SHIFT}"
ElseIf Label5.Text = "" Then
Label5.Text = "{SHIFT}"
ElseIf Label6.Text = "" Then
Label6.Text = "{SHIFT}"
End If
My.Settings.HK_SHIFT = 1
Button3.FlatStyle = FlatStyle.Flat
ElseIf MODz = "SHIFT" And Status = 0 Then
If Label3.Text = "{SHIFT}" Then
Label3.Text = Label4.Text
Label4.Text = Label5.Text
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label4.Text = "{SHIFT}" Then
Label4.Text = Label5.Text
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label5.Text = "{SHIFT}" Then
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label6.Text = "{SHIFT}" Then
Label6.Text = ""
End If
My.Settings.HK_SHIFT = 0
Button3.FlatStyle = FlatStyle.Standard
End If
If MODz = "WIN" And Status = 1 Then
If Label3.Text = "" Then
Label3.Text = "{WIN}"
ElseIf Label4.Text = "" Then
Label4.Text = "{WIN}"
ElseIf Label5.Text = "" Then
Label5.Text = "{WIN}"
ElseIf Label6.Text = "" Then
Label6.Text = "{WIN}"
End If
My.Settings.HK_WIN = 1
Button4.FlatStyle = FlatStyle.Flat
ElseIf MODz = "WIN" And Status = 0 Then
If Label3.Text = "{WIN}" Then
Label3.Text = Label4.Text
Label4.Text = Label5.Text
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label4.Text = "{WIN}" Then
Label4.Text = Label5.Text
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label5.Text = "{WIN}" Then
Label5.Text = Label6.Text
Label6.Text = ""
ElseIf Label6.Text = "{WIN}" Then
Label6.Text = ""
End If
My.Settings.HK_WIN = 0
Button4.FlatStyle = FlatStyle.Standard
End If
If Label3.Text = "" Then
Label2.Text = TextBox1.Text
Else
Label2.Text = Label3.Text + Label4.Text + Label5.Text + Label6.Text + " + " + TextBox1.Text
End If
My.Settings.HotKeyzKEY = TextBox1.Text
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Button1.FlatStyle = FlatStyle.Standard Then
HotKeyz("CTRL", 1)
Else
HotKeyz("CTRL", 0)
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If Button2.FlatStyle = FlatStyle.Standard Then
HotKeyz("ALT", 1)
Else
HotKeyz("ALT", 0)
End If
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
If Button3.FlatStyle = FlatStyle.Standard Then
HotKeyz("SHIFT", 1)
Else
HotKeyz("SHIFT", 0)
End If
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
If Button4.FlatStyle = FlatStyle.Standard Then
HotKeyz("WIN", 1)
Else
HotKeyz("WIN", 0)
End If
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Me.Hide()
TimeStamp.Show()
End Sub
Private Sub TextBox1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
x = e.KeyCode.ToString()
MsgBox(x)
If Len(x) > 1 And x <> "ControlKey" And x <> "Menu" And x <> "ShiftKey" And x <> "LWin" Then
TextBox1.Text = x
End If
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
'TextBox1.Text = x
If Len(x) > 1 And x <> "ControlKey" And x <> "Menu" And x <> "ShiftKey" And x <> "LWin" Then
TextBox1.Text = x
My.Settings.HotKeyzKEY = x
End If
If Len(x) = 1 Then
TextBox1.Text = x
My.Settings.HotKeyzKEY = x
End If
MsgBox(My.Settings.HotKeyzKEY)
If Label3.Text = "" Then
Label2.Text = TextBox1.Text
Else
Label2.Text = Label3.Text + Label4.Text + Label5.Text + Label6.Text + " + " + TextBox1.Text
End If
End Sub
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
My.Settings.HotKeyzKEY = TextBox1.Text
Dim key As System.Windows.Forms.Keys
Dim kc As New System.Windows.Forms.KeysConverter()
key = kc.ConvertFromString(TextBox1.Text)
hkr.Unregister(0)
Dim P1 As Integer
Dim P2 As Integer
Dim P3 As Integer
Dim P4 As Integer
If Label3.Text = "{CTRL}" Then
P1 = HotKeyRegistryClass.Modifiers.MOD_CTRL
ElseIf Label3.Text = "{ALT}" Then
P1 = HotKeyRegistryClass.Modifiers.MOD_ALT
ElseIf Label3.Text = "{SHIFT}" Then
P1 = HotKeyRegistryClass.Modifiers.MOD_SHIFT
ElseIf Label3.Text = "{WIN}" Then
P1 = HotKeyRegistryClass.Modifiers.MOD_WIN
End If
If Label4.Text = "{CTRL}" Then
P2 = HotKeyRegistryClass.Modifiers.MOD_CTRL
ElseIf Label4.Text = "{ALT}" Then
P2 = HotKeyRegistryClass.Modifiers.MOD_ALT
ElseIf Label4.Text = "{SHIFT}" Then
P2 = HotKeyRegistryClass.Modifiers.MOD_SHIFT
ElseIf Label4.Text = "{WIN}" Then
P2 = HotKeyRegistryClass.Modifiers.MOD_WIN
End If
If Label5.Text = "{CTRL}" Then
P3 = HotKeyRegistryClass.Modifiers.MOD_CTRL
ElseIf Label5.Text = "{ALT}" Then
P3 = HotKeyRegistryClass.Modifiers.MOD_ALT
ElseIf Label5.Text = "{SHIFT}" Then
P3 = HotKeyRegistryClass.Modifiers.MOD_SHIFT
ElseIf Label5.Text = "{WIN}" Then
P3 = HotKeyRegistryClass.Modifiers.MOD_WIN
End If
If Label6.Text = "{CTRL}" Then
P4 = HotKeyRegistryClass.Modifiers.MOD_CTRL
ElseIf Label6.Text = "{ALT}" Then
P4 = HotKeyRegistryClass.Modifiers.MOD_ALT
ElseIf Label6.Text = "{SHIFT}" Then
P4 = HotKeyRegistryClass.Modifiers.MOD_SHIFT
ElseIf Label6.Text = "{WIN}" Then
P4 = HotKeyRegistryClass.Modifiers.MOD_WIN
End If
hkr.Register(P1 Or P2 Or P3 Or P4, key)
End Sub
End Class
How can I send Numlock digits? I tried but failed.
Code:
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 : SendKeys.Send(System.Windows.Forms.Keys.NumPad7)
Case 1 : SenKeys.send("{NUMLOCK0}")
Case 2 : MessageBox.Show("D")
Case 3 : MessageBox.Show("F")
End Select
End If
How can I send Numlock digits? I tried but failed.
Code:
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 : SendKeys.Send(System.Windows.Forms.Keys.NumPad7)
Case 1 : SenKeys.send("{NUMLOCK0}")
Case 2 : MessageBox.Show("D")
Case 3 : MessageBox.Show("F")
End Select
End If
I'm not sure exactly, but my first suggestion would be not to use SendKeys.Send(). It may just be me, but I can never get it to work 100% of the time. So instead I always use keybd_event. Hope this helps.
Please rate if my post was helpful!
Per favore e grazie!
I am trying to create a global HotKey for a project with multiple forms. When a user press hotkey, I would like to add a current date to the active textbox control. I modified the code to something like this:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = HotKeyRegistryClass.Messages.WM_HOTKEY Then
Dim ID As String = m.WParam.ToString()
Select Case ID
Case 0
If TypeOf (Me.ActiveControl) Is TextBox Then
Me.ActiveControl.Text = Me.ActiveControl.Text.Insert(Me.ActiveControl.Text.Length, DateTime.Now.ToShortDateString)
Dim tb As TextBox
tb = Me.ActiveControl
tb.Select(Me.ActiveControl.Text.Length, 0)
End If
End Select
End If
MyBase.WndProc(m)
End Sub
How do I achieve this on all the forms in the project? Seems like it is tied to a form the HotKey is registered to. Any help? Thanks.
Hmmm, the only way I could think of is to continue processing everything through your main hook. There you can detect the "active" form within the scope of your project, then do with it what ever you so please.
Sorry to say I don't have much experience with ActiveControl, but the little I do have is that it's stays within it's scope (the form). So perhaps you can continue using this, but you'll first have to detect the active form, then go from there.
Please rate if my post was helpful!
Per favore e grazie!
Hi, i'm creating a program that has every internet radio station of my country and i've been thinking that it would be very nice that if it would be possible to change to another station with the keyboard even though a fullscreened game(directX) is up. I've tried this way but it doesn't seem to work when i am playing games, league of legends for an example. Any one here that can help me with this problem?
Truly excellent. I know this is old now, but it is still a good result in google, and the only one to be both simple and effective.
I've been trying to figure this out for ages. I managed it once years ago, and i couldn't for the life of me read the code i had managed.
Some of the top results in google have an asynchronous timers with ridiculous intervals to get when a key is pressed. Garbage.
This works perfectly - working fine on VS2015.
If option strict is on, make sure you cast the integer as string to prevent the error from appearing - From the excellent example the author provided "Case CStr(0) : MessageBox.Show("A")"
Edit: Just for others curiosity, if you don't want a modifier key, you can pass 'nothing' in place of the modifier - i.e "hkr.Register(Nothing, Keys.MediaNextTrack).ToString()"
Last edited by BlackerDeathMetal; Apr 5th, 2016 at 09:28 AM.
Reason: Additional help
How to make the same hotkey show and hide the form?
example: crtl+A hide the form, crtl+A again show the form if it is hidden
edit: did it Me.Visible = Not Me.Visible thanks