I'm writing an examination piece of software for my workplace and would like to know how I can trap and cancel key-presses such as:
ALT+F4
WIN+TAB
ALT+TAB
WIN
CTRL+ALT+DEL
I'm aware CTRL+ALT+DEL may not be possible, but if any of this is it'll be a step in the right direction!
Ideally I want to prevent the action, and then open a new form I've created saying 'Unauthorised keypress'
as #SQLHound link relates... us the FormClosing event to handle what happens when a user attempts to close. But if you want to block a boot attempt, then #Plutonix suggestion may help. Something along these lines...
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
Dim splashScreen as New Form
splashScreen.OpenDialog
e.Cancel=True
End Sub
Related
I've come across a peculiar focusing issue. I have created the following "search" program:
It runs in the background.
When you double-tap the Ctrl key it becomes visible.
You can type in the textbox because the form has focus.
If the form loses focus (I click on my desktop, for example), it disappears after 3 seconds.
I double-tap the Ctrl key again, and again it becomes visible.
But this time, no matter what I try, the form is not focused and I cannot type in the textbox without first manually clicking on the form.
What's particularly interesting is that when I run this program in debug mode from Visual Studios, the program regains focus upon double-tapping Ctrl key and becoming visible, and I can immediately start typing in the text box. However, when I build this program and run it alone, the program appears but does not regain focus upon double-tapping Ctrl key, and therefore I cannot type in the text box until I manually click the form.
After Me.Show() I have tried:
Me.Focus()
Me.Validate()
Me.Select()
Textbox1.Select()
Textbox1.Focus()
The form is topmost and normally running in administrator, but the same problem arises regardless.
The issue can be recreated in a more simple manner. Create a form with
Button ("Button1")
TextBox
Two timers ("hideForm", "showForm") both with intervals of 1000
Code:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
hideForm.Start()
sender.Enabled = False
End Sub
Private Sub hideForm_Tick(sender As Object, e As EventArgs) Handles hideForm.Tick
Me.Hide()
hideForm.Stop()
showForm.Start()
End Sub
Private Sub showForm_Tick(sender As Object, e As EventArgs) Handles showForm.Tick
showForm.Stop()
Me.Show()
Me.Activate()
End Sub
End Class
Click the button, and immediately click on a different window (so the form loses focus). Wait until the form is hidden and shown again. The textbox should have focus. Try typing.
If the program is run in debugging mode in Visual Studios, it works as expected. If you build the program and run it outside of VS, the form will reappear without focus, and you cannot type in the textbox without manually selecting the form.
Sorry for the long-winded explanation. It's a difficult issue to properly describe.
Try the form event handler Activate. Inside that method, you can use setFocus to gain focus for that particular Text Box. I know this answer is too late. But hope this helps someone.
Private Sub Form_Activate()
TextBox1.SetFocus
End Sub
Try an event handler for Form_Activate, and within that handler pass the focus to your textbox.
Instead of Focus, you can also try TextBox1.Select. This SO link provides some additional information and something about the difference between Focus and Select.
Select the Textbox you want to assign a focus to in the Design View Window.
Under the Properties window, set the TabIndex to 0 (zero).
I didn't even have to use the TextBox1.Focus() command. It still bothers me that the TabIndex overrides the Focus command.
What I tried (and worked for me), was to set the Focus() of the Textbox in the event handler Shown() [VB]:
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
Me.Textbox1.Focus()
End Sub
Note: the Select() method just didn't do the job. I hope this helps anyone else that comes with this same issue.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
MsgBox("test")
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
BackgroundWorker1.RunWorkerAsync()
End Sub
Once I click the Button1 ,Messagebox appears.When click okay with "Return" (enter) key it appears again and again...But when I click Return key permanently,almost 5 seconds later programs gives me the run time error.
Error is not English in my computer and I translated it.It is nearly mean "BackgroundWorker is busy,can't do two procces in the same time..."
I know that error.It is because of trying to run BackgroundWorker while it is running.In the code it just start with RunWorkerCompleted event.So it can't start again if "Work is not Completed".Who runs the BackgroundWorker ?
You need to read this post first, it talks about the dangers of re-entrancy and how dialogs (like MsgBox) solve the problem.
Which is what it is not doing in your program. A dialog can only be modal against other windows that are created on the same thread. That worker thread doesn't have any. So there is nothing that stops your Enter key press from also being seen by the control that has the focus. Button1. Note how you can simply use the mouse to select your main window and click the button. Kaboom.
That doesn't go wrong often enough as-is, you can help by leaning on the Enter key so it starts repeating. It will usually be detected by the message box window. But not always, there's a split second between DoWork ending and it starting back up. Just enough to give the UI thread a chance to see the keystroke. Now that Enter keypress operates Button1 and it starts the BGW back up again. So does the RunWorkerCompleted event handler, it cannot be started twice. Kaboom.
That's not the only problem with that dialog, you haven't discovered the other failure mode yet. A dialog needs an owner window, one that it can be displayed on top of. That message box does have one, it has to fallback to the desktop window. Now it is crapshoot which window is going to be in front. Could be the dialog, could be your main window. With the message box underneath your main window. The user cannot see it, has no idea that there is one. No taskbar button either.
Long story short: this cannot work. Only display UI on the UI thread. Only use a worker thread to do non-UI related work.
I am having a bit problems trying this. I must admit that I am still novice programming. Well, I managed for do this in this way (VB.NET):
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
If My.Computer.Keyboard.CtrlKeyDown Then
MORE IRRELEVANT CODE HERE
End If
End Sub
But with this way, even if it work, it dont let me customice the key shortcut (only Control, shift and others).
I did this too for try differents things:
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = GlobalVariables.own_key Then
MORE IRRELEVANT CODE HERE
End If
End Sub
I give value to GlobalVariables.own_key from other button. This work perfectly, but only if program have the focus.
So... With the first code program work even if it haven't the focus but only with few keys... And with the second it let me use any key, but don't work if it haven't the focus.
I tryed understand the "keyboard hook" but I must admit that I didn't understad it and couldn't manage for work any of them.
Using VB.net 2012.
Really thanks so much for your help
It may not be an answer you like but it is the answer. In .NET, you cannot get notification of keys when your application does not have focus and you cannot get mouse events outside your applications windows. If you looked into the "Keyboard Hook", you should have read that little important fact regarding VB.
Global hooks are not supported in the .NET Framework
I'd need a way to cause the program to crash on purpose when i click a button. But nothing comes to my mind that would still allow me to compile the program. any code that causes a hard crash for whatever reason. in particular i need it to close and not be able to continue. My beta testers need to test the recovery after crash feature. Thanks!
these things never happen when they should..
How about just throwing an unhandled exception?
Private Sub btnCrash_Click(sender As System.Object, e As System.EventArgs) Handles btnCrash.Click
Throw New System.Exception("The program has crashed catastrophically!")
End Sub
To effectively kill the process use Environment.FailFast() in a button click handler, like this:
Protected Sub buttonCrash_Click(sender As Object, e As EventArgs) Handles buttonCrash.Click
Environment.FailFast()
End Sub
This will not generate any exceptions, etc., it is the same as going to Windows Task Manager and killing the process.
Here is the documentation for Environment.FailFast Method (String)
How about the Environment.FailFast method?
Private Sub btn_click(...)
Environment.FailFast("Failure!")
End Sub
'This is the event that is fired as the application is closing, whether it
'be from a close button in the application or from the user
'clicking the X in the upper right hand corner
Private Sub Form1_FormClosing(sender as Object, e as FormClosingEventArgs) Handles Form1.FormClosing
'What we will do here is trap the closing of the application and send the application
'to the system tray (or so it will appear, we will just make it invisible, re-showing
'it will be up to you and your notify icon)
'First minimize the form
Me.WindowState = FormWindowState.Minimized
'Now make it invisible (make it look like it went into the system tray)
Me.Visible = False
End Sub
Hello again Stackoverflow!
Im trying to make an application that when you press X, the program gets put in system tray. But i have like no idea how i'm suppost to do that, so did a search on google and found this code. Only VB2010 (what i use) doesn't like the fourth line. Can anybody give me a quick tutorial on this, and make this work in VB 2010?
By the way, i will most likely use VB only tonight, just to make one application. So im not thinking of learing the whole language.
It looks like you found code over here Dream.In.Code: Minimize To System Tray
Did you "keep" reading the rest of the messages?
You need to add:
e.Cancel = True
to your FormClosing event or else the program just ends. Also, you need to add the NotifyIcon component and a ContextMenuStrip.