-
Limiting the Acceptance of Keyboard Interrupts
Hey Codeguru community, I need some quick advice on a problem and just found out that this site existed, hope I can find some help here.
I'm designing a program that will accept commands via the keyboard, I've already programmed the interrupts so that when they're pressed an action will occur depending on what key was pressed, but I want it to only interrupt the program after a certain button on the main form was clicked, my issue is that if I haven't clicked the button yet and keys are being quickly pressed one after another, the program will become constantly interrupted and will essentially freeze the form from accepting any clicking on any buttons or what-not.
My question is, is there a way to have the program accept interrupts after a certain event has passed, aka. I've clicked the button on the main form. I'm not sure if there's some sort of enable_interrupt variable or something that's intrinsically included in a VB program.
Any help would be appreciated, thank you.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Maybe a stupid suggestion from an old burnt-out programmer, but have you tried DoEvents?
-
Re: Limiting the Acceptance of Keyboard Interrupts
I'm not sure what that is, I'll look into it. Thanks for the suggestion.
-
Re: Limiting the Acceptance of Keyboard Interrupts
ummm sounds like you just need to add a flag in your code. In your code that processes the keys just test the flag and if not true then don;t do anything. In your button click set the flag to true.
-
Re: Limiting the Acceptance of Keyboard Interrupts
I do have a flag variable so that it only processes what I want after the button is clicked, but the issue is that every time a keyboard press is done, it calls the interrupt function regardless and then checks the flag, that check if done repeatedly essrntially freezes the main form ans that's what I'm trying to fix.
-
Re: Limiting the Acceptance of Keyboard Interrupts
I think you should show some code, an event such as keypress where the only thing there is a test of a flag var should not interfere with the program in any noticeable way also if the user is typing that fast they probably would not be clicking on anything anyway.
Then again I am not sure what you are really trying to say, you use the term keyboard interrupts but I think that maybe you mean something other than what that term implies.
-
Re: Limiting the Acceptance of Keyboard Interrupts
sure, like a keylogger? :(
-
Re: Limiting the Acceptance of Keyboard Interrupts
No not a keylogger, I'll post some code to make it clearer next time I'm at the computer with the project saved.
-
Re: Limiting the Acceptance of Keyboard Interrupts
If you're not already using the keyboard events of the form, then that would be the first thing to do. Then in the appropriate event, test the flag, and exit the sub if it is false.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Here's the event handling for a keypress, this is just part of it but if the keyboard is getting mashed on before "readyFlag" is true then it keeps checking this handler to check that variable even if it isn't set yet, and that constant rechecking basically freezes up the main form since the program keeps changing focus to this handler instead of the main code.
Code:
Sub MainScreen_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles Me.KeyPress
If e.KeyChar = ChrW(122) Then
If readyFlag = True Then
color1.BackColor = Color.Green
readyFlag = False
lblGO.Visible = False
End If
End If
End Sub
Is there a way to not have the program get to this handler code before the readyFlag is set to true? Even if keys are being pressed?
-
Re: Limiting the Acceptance of Keyboard Interrupts
Well... first of all this is not VB6 code but VB.Net so I am moving this to the VB.Net section.
If your readyflag var is defined properly then it will have a starting value of False before any event handler fires
Your readyflag test should be the outter test rather than the inner test, meaning you should test that first.
That said that code you posted would not do much and surely would not hang your program at all.
No you can not prevent the event from firing when a key is pressed unless of course you remove the event from your code.
Also note that your thread is mis titled as this has nothing to do with keyboard interrupts.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Code:
Sub MainScreen_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles Me.KeyPress
If readyFlag = False Then exit sub
If e.KeyChar = ChrW(122) Then
color1.BackColor = Color.Green
readyFlag = False
lblGO.Visible = False
End If
End Sub
That should help.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Thanks for the advice TT(n), unfortunately with that code I still run into the same problem, the program keeps changing focus to the keyhandler so if the keys are getting pressed rapidly in succession the main form still hangs and stops accepting button clicks lest I spam my clicks faster than the keyboard inputs.\
I'm just going to assume it can't be done the way I want, I was just hoping there was some global variable that would enable or disable keyboard inputs to the program, that I could change when I want the program to start accepting keyboard inputs.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Don't be frustrated just yet. We just didn't think the handler itself would cause a hang. I could see the overhead of calling ChrW for each repeat but not the boolen flag check. You have alternatives though. Although I wonder why your computer would hang unless there is a keyboard driver issue underlying. I've never seen it happen. If it really is caused by keys repeating at a rate that causes the handler to hang then try it only when the key is down or up:
Code:
Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.A Then
End If
End Sub
Private Sub Form1_KeyUp(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
If e.KeyCode = Keys.B Then
End If
End Sub
That will avoid what is called re-entrance.
And ofcourse this may be helpful as well to toggle the state of the handler:
Code:
Me.KeyPreview = True
-
Re: Limiting the Acceptance of Keyboard Interrupts
or, a bad keyboard itself. try on another...
-
1 Attachment(s)
Re: Limiting the Acceptance of Keyboard Interrupts
As others have stated, there shouldn't be an issue from repeated key presses. I tested with the attached form, and it works fine even if a key is held down. It does not prevent the button from being clicked.
I wonder if FilterKeys is on, and if that might be interfering. Check your keyboard settings for that.
Perhaps if you could explain why there would be rapid-fire keyboard events, it might shed some light on the issue.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Quote:
Originally Posted by
WizBang
As others have stated, there shouldn't be an issue from repeated key presses. I tested with the attached form, and it works fine even if a key is held down. It does not prevent the button from being clicked.
I wonder if FilterKeys is on, and if that might be interfering. Check your keyboard settings for that.
Perhaps if you could explain why there would be rapid-fire keyboard events, it might shed some light on the issue.
Would holding down a button repeat the keyhandler function? I suppose it would
Filter Keys is not on, but that was a good guess.
I made the program as sort of a trivia game, I have several controllers attached and sending input via Joy2Key as a workaround of me not knowing how to program direct input from a game controller, thus when a button is pressed on the controller it sends a keyboard input to the program. Essentially I click a button when it's time for the contestants to enter their answer, but if they're already mashing the button beforehand (all 4 of them in worst instances) it essentially hangs my program so when I try and click the button on the form it doesn't register my click, until I click fast enough that I get one in in-between all the button mashing.
The ButtonDown and Up separate functions seem like a good workaround, it'd probably cut the load in half, I'll try that.
-
Re: Limiting the Acceptance of Keyboard Interrupts
I think that the keypressed event does not fire until the key is released so no it should not continue to fire if the key is held down.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Ah! That's probably the problem - Joy2Key. Perhaps if you only activate the Joy2Key utility when you click the button, and deactivate it when the first valid signal is received from one of the controllers, then there might not be a hanging issue. You might also play a sound whenever a player tries to press a button before it should be accepted. I also wonder if calling DoEvents first, within the keyboard event, might allow your mouse click to get through. However, I'd still recommend learning to use the API functions associated with joystick input signals. Then you'd not have to deal with such external software.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Ok that is why the problem was not easy to diagnose. You are using Joy2key and not the physical keyboard. Now it makes sense why you posted the subject as interrupts.
Have you tried it with the handler fully commented out?
Just make sure it's not on the joy2key side.
EDIT: Is that the only code you have in the key event?
If you have any code that takes a long time to execute that has not been posted then you will need to use a thread or backgroundworker.
-
Re: Limiting the Acceptance of Keyboard Interrupts
Quote:
Originally Posted by
Chumara
Code:
Sub MainScreen_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles Me.KeyPress
If e.KeyChar = ChrW(122) Then
If readyFlag = True Then
color1.BackColor = Color.Green
readyFlag = False
lblGO.Visible = False
End If
End If
End Sub
I have this code repeated 5 times, checking for different ChrW values. I wish I knew more about programming and I admit I have no idea how to program in joystick inputs, but I feel stupid for repeating that readyflag check 5 times, I think just pulling that out of my If statements will lessen the problem a bit. It's really hard for me to test these ideas because I can't emulate 5 people mashing 5 buttons in rapid succession by myself, I can't even recreate my current issue by myself, it's only while using it in it's practical use that I run into this problem. I appreciate the help, but I think I'll just deal with it for now and hope that pulling the readyflag out of the If statements solves the problem a bit.
What I had hope existed in VB I guess doesn't exist after all.
EDIT: Nevermind, apparently if I just use my keyboard to hit all 5 keys in succession it emulates the problem, I was trying to hold them down like WizBang had said and hadn't run into trouble. Pulling the readyflag check out is better in terms of principal, but still didn't get rid of the issue, also I was doing this without Joy2Key so I guess I can't blame that. I was really hoping there was some way of turning off and on the keyhandler. Maybe if I embed the keyhandler inside an infinite do while loop?
-
Re: Limiting the Acceptance of Keyboard Interrupts
You are doing the ChrW function over and over. Your boolean readyflag check should be before that. This boolean check is ok, it doesn't cost much. That data type is the least expensive to check.
Did you try it with the keydown handler?
Quote:
I was really hoping there was some way of turning off and on the keyhandler.
There is.
Here is one more example of how to turn the handler off just like you want. I posted this before.
Code:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Me.KeyPreview = True
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Me.KeyPreview = False
End Sub
Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
MsgBox("pressed " & e.KeyCode.ToString)
End Sub
-
Re: Limiting the Acceptance of Keyboard Interrupts
Oh cool, sorry I missed that. So I can put Me.KeyPreview.False in the main form so it initializes that way, then set it to True when I click the button to start accepting inputs, and then set it back to False after the ChrW/button checks? I'll try it right now, this might have been the simple answer I was looking for.