As in the event Form Closing I want to show a msgbox asking if I really want to put PC in to sleep mode and cancel the sleep order if the user answer "No".
I need to detect this even if the application is minimize or out of focus.
Thanks.
I don't have a sleep button on my keyboard, so I can't verify,
but this might be worth a test...
In your active forms KeyDown event, put something like this:
Private Sub form_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)Handles Me.KeyDown
Select Case e.KeyCode
Case Keys.Sleep
'Do something when the sleep button is pressed
End Select
End Sub
If you want the keypress to not get sent to the active control in the form, add
e.Handled = True
I have learnt that in order for the main form to capture keypresses, the "KeyPreview" property of the form must be set to "True". If not the keypress will be sent to the control with focus.
I have also seen that there are differences in what keys can be detected in the KeyDown event and the KeyPress event. As an example, you can test for an arrow key in the KeyDown event, but not in the KeyPress event, as they are using a different event argument type, so it is worth checking both if you can't find the key you are looking for.
As to making it work when the program is not in focus, that appears to be more difficult. The following link shows how to register a HotKey which you can trap even when your program is not in focus: http://www.kirsbo.com/How_to_add_global_hotkeys_to_applications_in_VB.NET
However, looking at the available key-codes to trap, I can not fins a Sleep or Power option. They can be found here: http://msdn.microsoft.com/en-us/library/ms927178.aspx
As I said, I can't verify that this works, but if you can, make a comment so other people will know.
Related
Using VB.net for a windows form application. I'm tired of always having to backspace the default '0' of a numeric updown control. What I would like to do is have the value selected automatically on enter, so that I can just type over it.
I've tried this:
Private Sub updown1_Enter(sender As Object, e As EventArgs) Handles updown1.Enter
Me.updown1.Select(0, updown1.Text.Length)
End Sub
I've used a break point to verify that it does indeed run, but it doesn't seem to do anything. What am I missing?
Your code is actually selecting the value as intended, it is just being undone by a mouse event almost instantaneously. When you click to enter a NumericUpDown, the events fire in the following order:
Enter
GotFocus
MouseDown
Click
MouseUp
As you probably know, in controls with text fields the native behavior places the cursor wherever you've clicked inside the textbox. This is what's causing your problem. You have selected the text at Enter, but then a bunch of mouse events come along and undo all your hard work. The obvious solution is to just use the MouseUp event since that's at the end of the list, but MouseUp will fire for anywhere you click inside the control so you'll have to decide if that behavior is acceptable for you.
I have been working on a large game project lately and have been though a couple methods for detecting keyboard input. For movement I use getasynckeystate (which is perfect) because it sends a signal every tick that the key is being pressed.
Then comes the other method, which is keydown. This method works with single keypresses, but then a second later starts spamming the keypress action.
My goal is to find something that will only detect your keypress once, even if you hold down the key; once you let go of the key it will let you hit it again. Please help and thanks for reading this!
Examples:
if GetAsyncKeyState(Convert.ToInt32(Keys.W)) then....
if e.keycode = keys.B then....
The 'keyUp' event captures the key that was pressed or which remained pressed only once:
Sub Control_KeyUp(sender As Object, e As KeyEventArgs) Handles Control.KeyUp
MsgBox("Pressed key: " & e.KeyCode.ToString())
End Sub
Edit: Removed Private access so it can be called from another class.
I have a timer that each time displays a message box saying "Hello." I also have the code configured so whenever the window loses focus, it should stop the timer that keeps the boxes coming. However, they keep coming.
I have tried a similar thing in a similar program with way too long of code to post here, but what it did was it paused the first time, stop the timer, and when the timer was stopped again, it didn't work correctly. There was also some other code there that had a random element, that displayed a different prompt when a certain number was generated, but once it was generated, it kept using that same different prompt every time.
Is this a error of not enough time to process all the code and it "overlaps" some? I can delay the timer without that much different effects, but I think that my [lower end] CPU that it is running this program on, that with 1.6 GHz that it could handle a timer with a few message boxes. Though, VS is running at the same time, but I shouldn't have to export my code and close VS everytime that I need to test it.
If the problem is not enough time, is there a way that I can prevent my program from "multithreading" or whatever it is doing? It seems like a weird problem, but computers are very weird too. :P
Edit:
By "Focus" I mean the selected window that is the most apparent. For example, my browser is now "focused." I have been informed that the correct term is "selected." I must have been using the wrong type of event trigger... :P
It doesn't generate a lost-focus event because the form doesn't have the focus in the first place. A control on the form always gets the focus, like a Button or TextBox. You could use the Deactivate event instead.
Or just not display the message box when the Tick event fires again. Roughly:
Private ShowingMsgBox As Boolean
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'' Do stuff
''
If Not ShowingMsgBox Then
ShowingMsgBox = True
MsgBox("yada")
ShowingMsgBox = False
End If
End Sub
The underlying reason for this behavior is that MsgBox pumps a message loop. It keeps normal Windows messages getting delivered, like WM_PAINT that keeps the windows painted. And WM_TIMER, the one that generates the Tick event. The only kind of messages that it blocks are input events, mouse and keyboard messages. Otherwise the reason that Application.DoEvents() is so very dangerous. It does the same thing as MsgBox() does, without disabling input.
Create a new project with a Timer (Timer1) and write this code:
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
If (Me.Focused) Then
MessageBox.Show("Hello")
End If
End Sub
If you put the mouse over your form, you would see that a message box will popup after the given Interval is over. If you don't click on the accept button and keep the mouse on the form, you would see that no further messages appear: Me.Focus is False. If you click on the accept button, the messages would start poping up; you don't even need to select the form (the focus is transferred automatically from the MessageBox to the Form).
Summary: the MessageBox does make the Form to lose the focus, although it is a kind of a "tricky" lost as far as will automatically come back after clicking on the accept button.
UPDATE: the proposed configuration does trigger a LostFocus event of the form:
Private Sub Form1_LostFocus(sender As Object, e As System.EventArgs) Handles Me.LostFocus
MsgBox("lost")
End Sub
Unlikely the other answers/comments, what I understood from your question is that you want to know the reason and if this is a normal behaviour, rather than getting a working solution to make the form to lose the focus (you are not even describing the exact conditions under which you want this to happen).
(This should be an easy one... but Googling for it is a mess of rabbit trails.)
I have a Windows Forms app, with a TabControl. On the first tab (which is a bunch of textboxes), the CNTL-x/c/v keyboard shortcuts for cut/copy/paste work as expected. On the second tab (which is a DataGridView), the keyboard shortcuts don't do anything.
How do I hook up these keypress events to my cut/copy/paste routines?
Please note: I already have great cut/copy/paste routines for my DataGridView--and they work fine when launched from the tooltip buttons or menus. I just need to hook up those subs to the CNTL-x/c/v keypress events.
You should already have one or more of the following events for your control: KeyPress, KeyUp, and KeyDown.
Handle those events like you would any other. In your event handler you can do a check against the arguement provided to see if any control keys are/were pressed and which other keys have been pressed as well.
If the correct combination of keys have been pressed you can add things to the clipboard or attempt to copy from the clipboard to your control.
From Matthew's tip, I was able to put together the following working code ('DGVCutCopyPaste' is, of course, my class for cutting/copying/pasting multiple cells in a DataGridView--not a built-in):
Private Sub DataGridView1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles DataGridView1.KeyUp
If Control.ModifierKeys = Keys.Control Then
Select Case e.KeyCode
Case Keys.X
DGVCutCopyPaste.CutDGVCells(DataGridView1)
Case Keys.C
DGVCutCopyPaste.CopyDGVCells(DataGridView1)
Case Keys.V
If Clipboard.ContainsText Then
DGVCutCopyPaste.PasteDGVCells(DataGridView1)
End If
End Select
End If
End Sub
I had some trouble with the "KeyPress" event (which has a different signature), but the "KeyUp" and "KeyDown" work fine this way.
My problem seems to be quite simple, but it's not working the intuitive way.
I'm designing a Windows Forms Application, and there is a dialog that should NOT exit when the enter key is pressed, instead it has to validate data first, in case enter was pressed after changing the text of a ComboBox.
I've tried by telling it what to do on KeyPress event of the ComboBox if e is the Enter key:
Private Sub ComboBoxSizeChoose_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles ComboBoxSizeChoose.KeyPress
If e.KeyChar = Convert.ToChar(Keys.Enter) Then
Try
TamanhoDaNovaFonte = Single.Parse(ComboBoxSizeChoose.Text)
Catch ex As Exception
Dim Dialogo2 As New Dialog2
Dialog2.ShowDialog()
ComboBoxSizeChoose.Text = TamanhoDaNovaFonte
End Try
End If
End Sub
But no success so far. When the Enter key is pressed, even with the ComboBox on focus, the whole dialog is closed, returning to the previous form. The validation is NOT done at all, and it has to be done before exiting. In fact, I don't even want to exit on the form's enter KeyPress, the only purpose of the enter key on the whole dialog is to validate the ComboBox (but only when in focus, for the sake of an intuitive UI).
I've also tried appending the validation to the KeyPress event of the whole dialog's form, if the key is Enter. NO SUCCESS! It's like my code wasn't there at all.
What should I do?
(Visual Studio 2008, VB.NET)
Make sure you don't have a Button on the dialog that is set to something other than DialogResult.None.
For example, if you have a button set to DialogResult.OK, it will act as the "default" button and close your form.
Although not your answer, I would recommend against using exceptions to control logic flow. That said, try Single.TryParse instead to make your flow less...well, exceptional.
To change the behavior you are seeing, change the dialog's AcceptButton from your Ok button to none. Changing that button's DialogResult to None doesn't keep the click event from firing, only from closing the dialog. Although the behavior may sound like something you desire, the result does not.