Multiple Keyboard Shortcuts - vb.net

I am using the following code to try and get Ctrl+S to press a toolstrip button:
Private Sub take_register_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.S And Keys.Control Then
ToolStripButton20.PerformClick()
End If
End Sub
I am a newbie at this, so I dont understand millions of lines of coding, so can you please keep it as simple as possible :-) .

Total guesswork here since there is no actual question. First, in order to get something like that work, you need to set KeyPreview = True for the form. Next, you probably want to use the KeyDown event instead of KeyPress:
Private Sub Form1_KeyDown(...)
' when possible use AndAlso for speed and to avoid some errors in
' some situations. if e.Control is False, the second part wont be evaluated.
If e.Control AndAlso e.KeyCode = Keys.S Then
ToolStripButton20.PerformClick()
End If
End Sub
To repeat: you can simply assign a shortcut key combo to the menu object in the designer and let .NET do all the work. ...and I don't know where "multiple" comes in to play unless Ctrl+S counts as multiple somehow.

Related

How do i detect Alt + Tab Key and then close the form?

I want to close my form when Alt + Tab is pressed. However, The form is somehow not registering the key combination.
i have tried to use the Me.KeyUp event to detect the keys
Private Sub Menu_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
Select Case e.KeyData
Case (Keys.Alt + Keys.Tab)
Close()
End Select
End Sub
How can it be done ?
Try this: As in my comment Alt+Tab would not work. So try something else like Alt+Q. Put this code under the Form's keydown event.
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If (e.KeyCode = Keys.Q AndAlso e.Modifiers = Keys.Alt) Then
Me.Close()
End If
End Sub
You need to set the form's Set KeyPreview to True for it to respond to the key events, but since Alt + Tab is a special windows combination the key events will not be fired.
Try in this way
Dim myval As Integer 'this is global variable declare
Private Sub Menu_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
Select Case e.KeyData
Case (Keys.Alt)
myval = 1
Case (Keys.Tab)
If myval = 1 Then
Me.Close()
End If
End Select
End Sub
May be my syntax in not correct, please edit it if anything is notok.
I managed to work around this problem using this method-
That's usually the ESC key. One key press. A common one. Maybe you want to handle the Form's deactivate event, instead. – Jimi
I used the forms deactivate event to close it, since Alt+Tab is basically deactivating the form!
(A workaround because Alt+Tab as keystrokes were not detected by any means, as mentioned by
the last two answers.)
My final code looks like this -
Private Sub Menu_Deactivate(sender As Object, e As EventArgs) Handles Me.Deactivate
If loaded = true Then
Close()
End If
End Sub
I had to check if loaded (a boolean i declared to be set to true when everything is loaded)
to be true because my form opens one other form while loading, which inadvertently deactivated the main form and closed it!
Thank you so much for helping me everyone!!
Edit: I needed to clarify that the second form is always behind my main form so it is never really clicked on. I did this as a workaround to have aero blur in my application without a bug i experienced while applying it to the main form - it is too light, so text is unreadable. So i set another form to show aero blur and always stay behind my main form, whose opacity I have set to 0.88. This gives me a lot of control over the look of the blur.

Why does MessageBox has an affect on SuppressKeyPress?

Here is a peculiar situation in vb. I was messing the with SuppressKeyPress property and I found out something strange.
The Situation
Lets say I have a text box called txtName, and I want the name to be without any numbers, and when a number is inserted, a MessageBox will pop out and report an error.
Private Sub TextBox1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtName.KeyDown
If e.KeyCode >= Keys.D0 And e.KeyCode <= Keys.D9 And _
e.Modifiers <> Keys.Shift Then
e.SuppressKeyPress = True
MsgBox("Error - A Number has been pressed")
'The number appeared in the text box.
End If
End Sub
In this case, for some strange reason, if I type a number, it will be written in the text box, although I suppressed the keypress.
What I found out is that if I remove the MsgBox line, the number will not appear in the text box.
Private Sub TextBox1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtName.KeyDown
If e.KeyCode >= Keys.D0 And e.KeyCode <= Keys.D9 And _
e.Modifiers <> Keys.Shift Then
e.SuppressKeyPress = True
'The number did not appear in the text box.
End If
End Sub
Question
What is going on? Why the MsgBox "allows" the key to be pressed? Why it has any effect on the SuppressKeyPress property?
This is a pretty typical side-effect of using MessageBox, it can cause lots of tricky to diagnose problems. The SuppressKeyPress property is implemented by searching the message queue for any keypress events and removing them. But that can happen only after your event handler completes.
Trouble is, it isn't completing any time soon. Your MsgBox() call is taking over and it starts pumping a message loop by itself. Like dialogs do, the equivalent of calling the infamous DoEvents() method. And it will readily dispatch the pending messages in the message queue, including those keypress messages that were supposed to be suppressed.
A band-aid for such a problem is to display the message box later, after the event handling is completed and Winforms had a chance to purge the keypress messages. Elegantly done by using the Control.BeginInvoke() method:
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode >= Keys.D0 And e.KeyCode <= Keys.D9 And e.Modifiers <> Keys.Shift Then
e.SuppressKeyPress = True
Me.BeginInvoke(New Action(Sub() MsgBox("Error - A Number has been pressed")))
End If
End Sub
But the real fix is to use the correct event. You should always use the KeyPress event instead for this kind of filtering. That also avoids the very painful dependency on the user's active keyboard layout that's always present when you use KeyDown. Fix:
Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
If e.KeyChar >= "0"c AndAlso e.KeyChar <= "9"c Then
e.Handled = True
MsgBox("I don't like digits")
End If
End Sub
But then again, don't use message boxes to slap the user for making a simple mistake.
I found a little 'hack' for those who dont want to mess with Invoking methods, starting new threads manually etc.
My (old) code that didnt work was
Private Sub textEditKeyPress(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.KeyValue = 220 Then
e.SuppressKeyPress = True
MessageBox.Show("\ not allowed. Use / instead.")
End If
End Sub
By changing the code to
Private Async Sub tEditDropBoxFolderName_EditValueChanged(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.KeyValue = 220 Then
e.SuppressKeyPress = True
Await Task.Delay(100)
MessageBox.Show("\ not allowed. Use / instead.")
End If
End Sub
Everything works fine, and i havent found any side effects by using this.
(Code was translated by c#, maybe it needs some modifications for vb.)
So I tested your code and I can reproduce this behavior. I think the reason as to why this is happening is because the MsgBox (a modal dialog) will call Application.DoEvents resulting in the message being processed.
By replacing
MsgBox("Error - A Number has been pressed")
with
Application.DoEvents
you'll get the same result.
You should read Hans Passant's answer in the following SO post. He provides a good explanation about the relationship between ShowDialog (ref. MsgBox) and DoEvents.
Use of Application.DoEvents()

VB 2008 net keycode

Can anyone help on how to disable the alt + ctrlkey in vb.net. I am not using any button to disable. But by default it should start function disable to keys once the application starts.
You can use the SuppressKeyPress Property. I'm not sure what you are trying to do, but lets say that you dont want a certain key to effect a textbox change. Lets say you don't want the key G to be written in the text box. You can write to following code:
Private Sub TextBox1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode = Keys.G Then
e.SuppressKeyPress = True
End If
End Sub
This code will prevent the key G to be written in the text box. Hoped it helped :)

On key release handler

So, what I'm trying to do is run a piece of code when a button is pressed (I'll use the right-arrow key for the time being), and keep running it in a loop until that key is released.
So, my current code looks something like this (I've simplified it, because it's using SerialPorts, and is not easy to understand code):
Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
Select Case e.KeyCode
Case Keys.Right
Do Until (CODE LOOKING FOR RIGHT-ARROW KEY RELEASE)
SerialPort1.Write("right")
Loop
e.Handled = True
SerialPort1.Close()
End Sub
Ultimately, what I'm trying to do is control and arduino through the serial port function. I've wired it up to a cheap rc car (I usually have a few arduino projects on the go), and have code which allows me to control it by arrow keys in the IDE itself.
However, I have limited VB.NET knowledge (I've only been at it a few years), so I'm kinda struggling along with the help of Google, which was a god end while trying to work out how to keep the serialport open (it kept closing due to a logic error in my code).
The goal is that once I can control it by arrow keys in VB.NET, I can set up a more advanced program which will allow pre-programming routes (for example, I can try to "teach" the car sets of instructions so that I can get it to automatically follow a circuit, and load various pre-programmed routes into it). I'd also plan an on-screen gui to show what button was pressed, and whatever else I think of.
Also, given this is a prototype, I intend to eventually hook up the arduino and VB program to my hobby grade rc, and see if I can get the computer program, with pre-programmed isntructions, to beat my round my track.
Well, after that little essay, I guess it's just thanks in advance, and any advice in other areas of my project is also appreciated =)
Why make this complicated. It looks like you want to send something as long as the key is down, and then close the port when it is released.
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Right AndAlso keydelay >= 1 Then
Debug.WriteLine("DWN") 'SerialPort1.Write("right")
e.Handled = True
ElseIf e.KeyCode = Keys.Right Then
keydelay += 1
End If
End Sub
Dim keydelay As Integer = 0
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If e.KeyCode = Keys.Right Then
keydelay = 0
Debug.WriteLine("UP") 'SerialPort1.Close()
End If
End Sub

How to make a KeyDown work twice

I am working on a little story type thing in visual basic. Nothing too complicated but i have run into a problem. I am trying to make a pause feature. I have it all working to when i press escape, the form goes into a menu type thing. The only problem is that it only works once. The first press works, but if i hit continue, it continues from where i left off. But if i press it again, nothing happens. Here is the code i am using:
Private Sub Story_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Escape Then
Text.Hide()
Background.Hide
ContinueButton.Show
OptionsButton.Show
End If
End Sub
Is there any way for me to make this work more than just once? I am using a KeyDown event in a private sub.
Hope this made sense, but thanks for any help guys!
You're using Form.KeyPreview = true to capture the form keystrokes. I think Text.Hide() or one of Show operations could be the problem such as getting the TabStop's out of order or leaving a gap in the tab sequence.
Try resetting the controls or using SendKeys to reset the tab sequence index (to the approriate a control to have focus), For example, Tab forward and Alt Tab back:
SendKeys.Send("{TAB}");
or
SendKeys.Send("%{TAB}");
Ref:
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send(v=vs.110).aspx
Using a class level boolean as toggle should work:
Dim Hide As Boolean = False
Private Sub Story_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Escape Then
Hide = Not Hide
If Hide Then
Text.Hide()
Background.Hide
ContinueButton.Show
OptionsButton.Show
Else
Text.Show()
Background.Show
ContinueButton.Hide
OptionsButton.Hide
End If
End Sub
If nothing else helps, you can always have a private class-level variable like _processingKeyDown, set to True at handler start, and then to False when done. The first line in the handler would be:
If _processingKeyDown Then Return