Not checking for control key pressed properly - vb.net

I got this timer tick function:
Private Sub controlTick(ByVal sender As Object, ByVal e As EventArgs)
Label2.Text = (Control.ModifierKeys = Keys.Control)
End Sub
That is supposed to make my label say "True" if I am currently holding down the Control key, and "False" if I am not.
But, how come my label is always "False"? What is interesting is that if I press the Control key at lighting speed a bunch of times I can see for a fraction of a second "True", but immediately turns to "False".
Timer ticks every 50ms.
I do not understand.... any ideas?

I can't reproduce the behavior you describe... I tried creating a new WinForms project, placed a Label control on the middle of the form, and added a Timer control.
Whenever I press the Ctrl key, the label reads True. Otherwise, it reads False. Exactly the behavior you would expect to see. I don't have to press anything at lightning speed.
(Edit: It doesn't break when more controls are placed on the form either. What are you doing differently?)
My code looks like this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
' Start the timer
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
' Update the label
Label1.Text = (Control.ModifierKeys = Keys.Control).ToString
End Sub
Only difference is that you're apparently compiling without type checking enabled (Option Strict Off).
I always prefer to code in VB.NET with this turned on (check your project's Properties window), in which case you have to explicitly convert the boolean type to a string type using ToString.

I have created a winform application to prove this.. I am using the form and I have set the "KeyPreview" property to true and for every key pressed I get the code correctly.
Please check again using the way I mentioned and let me know if it resolves.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show(e.KeyCode.ToString());
}
Also for Control key the code is (e.KeyCode == Keys.ControlKey)....

I'm not sure this will help, but try using HasFlag, because maybe there is some other flag in ModifierKeys which is also on:
http://msdn.microsoft.com/en-us/library/system.enum.hasflag.aspx

Related

Disable password TextBox Caps-Lock is On warning

I am creating a login thing and I have this problem that every time I click on this "Show Password" Button and the Caps-Lock is activated, a Warning pops up and won't leave (at least I think it won't, which for the end-user would be even worse)
I would like to get rid of this warning completely.
Before redirecting my question to this question:
How to disable system's caps-lock notification on Textbox
I have already tried that.
Private Sub ShowPassword_MouseDown(sender As Object, e As MouseEventArgs) Handles ShowPassword.MouseDown
If txt_Password.Text <> "" Then
txt_Password.UseSystemPasswordChar = False
End If
End Sub
Private Sub ShowPassword_MouseUp(sender As Object, e As MouseEventArgs) Handles ShowPassword.MouseUp
If txt_Password.Text <> "" Then
txt_Password.UseSystemPasswordChar = True
End If
End Sub
The warning should disappear.
Hope this question can help other people other than just me.
Edit: Thanks Jimi. :D
When you do this:
[TextBox].UseSystemPasswordChar = [Bool Value]
the handle of the control is recreated each time (.Net source code)
The baloon tooltip will be shown for the new control handle, as soon as the TextBox.Text value changes: the tooltips will pile up.
A simple workaround - since disabling the warning may not be a good choice here - is to set the PasswordChar property to Char.MinValue or Nothing in the MouseDown handler of your Show Password Button, then set it back to the previous value on MouseUp. This won't recreate the handle (.Net Source code) and the balloon tooltip can be disabled pressing the Caps-Lock key.
Set UseSystemPasswordChar to False in the Designer.
In Form.Load or txt_Password.Enter: txt_Password.PasswordChar = ChrW(&H25CF)
Private Sub ShowPassword_MouseDown(sender As Object, e As MouseEventArgs) Handles ShowPassword.MouseDown
txt_Password.PasswordChar = Char.MinValue
End Sub
Private Sub ShowPassword_MouseUp(sender As Object, e As MouseEventArgs) Handles ShowPassword.MouseUp
txt_Password.PasswordChar = ChrW(&H25CF)
End Sub

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.

How do I prevent mouse wheel from incrementing numericupdown without over loading?

How do I prevent mouse wheel from incrementing numericupdown without over loading?
I had previously inherited numericupdwon to overload the MouseWheel event with an empty event. This worked for a while, but something happened when I switched to x64 that made the whole inherited class periodically show not found. Not sure because even if I switched back to x86 it was still a problem.
This worked for me..
Private Sub NumericUpDown1_MouseWheel(sender As Object, e As MouseEventArgs) Handles NumericUpDown1.MouseWheel
Dim MW As HandledMouseEventArgs = CType(e, HandledMouseEventArgs)
MW.Handled = True
End Sub
That HandledMouseEventArgs usage does look weird though.. but it works.
https://msdn.microsoft.com/en-us/library/system.windows.forms.handledmouseeventargs(v=vs.110).aspx
I came up with a different solution, using the following code to prevent the increment
Private Sub nup_cores_MouseWheel(sender As Object, e As MouseEventArgs) Handles nup_cores.MouseWheel
nup_cores.Increment = 0
End Sub
And then change it back. In the specific case of a numericupdown, the cursor blinking seems to trigger gotfocus. The same principle could be applied with a short duration timer
Private Sub nup_cores_GotFocus(sender As Object, e As EventArgs) Handles nup_cores.GotFocus
nup_cores.Increment = 1
End Sub
For C#:
For some reason the MouseWheel doesn't show up in the list of events from the GUI. So I had to programmatically add the event in my form load. In the MouseWheel event I do something similar as the above selected answer (but a little different).
private void Form1_Load(object sender, EventArgs e)
{
numericUpDownX.MouseWheel += new MouseEventHandler(handle_MouseWheel);
}
void handle_MouseWheel(object sender, MouseEventArgs e)
{
((HandledMouseEventArgs)e).Handled = true;
}

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

NumericUpDown.value is not saved in the User Settings

I have a NumericUpDown Control on a form. In the Application Settings / Properties Binding, for the value parameter, i can't select my USER setting called : Heures (Integer / User).
I tried to save the value by this way :
Private Sub NumericUpDownHeures_Leave(sender As System.Object, e As System.EventArgs) Handles NumericUpDownHeures.Leave
My.Settings.Heures = NumericUpDownHeures.Value
My.Settings.Save()
End Sub
But it's not saved.
No problem for other settings (String / User). But i don't understand why the settings (Integer / User) are not saved.
Please help, Thanks.
As you are putting "NumericUpDown1.Value" you have to set the value at My.Settings.Heures to decimal.
In Form1_Load add:
NumericUpDownHeures.Value = My.Settings.Heures
and add to the event listener for your button or other widget:
My.Settings.Heures = NumericUpDownHeures.Value
I would guess the issue is that the Leave event is not being fired as you expect it to be, especially if the user just clicks the up/down arrows. I suspect that it is only fired when the user actually clicks into the value area, then leaves. You could verify this by debugging to see if your code is ever hit or by showing a simple msgbox from that event.
I think that you will have better luck if you hook the LostFocus or ValueChanged event.
I want to add to this as well for anyone looking at this in the future.
Save your settings as shown already by putting
My.Settings.Heures = NumericUpDownHeures.Value into your ValueChanged event, and then doing reverse in the form load event.
The problem is, this value changed event fires before the form load when you first initialize, so it will keep defaulting to whatever value you have set in the designer because you're overwriting the setting value with the designer value.
To get around this, you need a private/public boolean at the top of your code that is only set to true once your form has loaded (set to true at the bottom of your form_load event), then you can add the condition to the ValueChanged event checking if the form is loaded yet or not. If it is, then change the setting value, if not, then don't.
An example:
Private IsFormLoaded As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
NumericUpDown1.Value = My.Settings.SavedNumValue
IsFormLoaded = True
End Sub
Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
If IsFormLoaded = False Then Exit Sub
My.Settings.SavedNumValue = NumericUpDown1.Value
End Sub
OR
Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
If IsFormLoaded Then
My.Settings.SavedNumValue = NumericUpDown1.Value
End If
End Sub