By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,644 Members | 2,105 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,644 IT Pros & Developers. It's quick & easy.

exit loop by pressing a key and come back

P: 7
Gentlemen I cannot figure out the following:
I have a loop in
Expand|Select|Wrap|Line Numbers
  1. Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Pressing a key I am checking what key was pressed and come back to the loop.

Thanks for help
Dec 29 '07 #1
Share this Question
Share on Google+
11 Replies


100+
P: 274
Can't understand what really you want to know. If you want to check which key was pressed it can be done in keypress of the form.

Expand|Select|Wrap|Line Numbers
  1. Private Sub Form_KeyPress(KeyAscii As Integer)
  2. msgbox KeyAscii 
  3. End Sub
Dec 29 '07 #2

Expert 5K+
P: 8,434
...Pressing a key I am checking what key was pressed and come back to the loop.
Can you please try to explain in more detail what the problem is? I didn't get it either.
Dec 29 '07 #3

P: 7
Sorry gentlemen, my fault.

I am trying to create a "game" for my 6 year old son to learn keyboard letters.
I have a loop with an image of a letter that flies all over the screen until a key of keyboard is pressed to check if the pressed key is correct one.
So flying letter:
Expand|Select|Wrap|Line Numbers
  1. Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
  2.  
  3.         'flying baloon
  4.         Dim y_Max As Integer = Me.Size.Height()
  5.         Dim x_Max As Integer = Me.Size.Width()
  6.         Dim x As Integer = x_Max / 2 - x_Max / 4
  7.         Dim y As Integer = y_Max - 150
  8.         Dim letter(26) As Image
  9.         Dim count As Integer
  10.         Dim a As Integer = 1
  11.         Dim b As Integer = -1
  12.         'Dim z As Integer
  13.         Dim KeyAscii As Integer
  14.         Dim KeyChar As Integer
  15.  
  16.         letter(1) = My.Resources.E
  17.         letter(2) = My.Resources.I
  18.         letter(3) = My.Resources.O
  19.         letter(4) = My.Resources.Q
  20.         letter(5) = My.Resources.R
  21.         letter(6) = My.Resources.T
  22.         letter(7) = My.Resources.U
  23.         letter(8) = My.Resources.W
  24.         letter(9) = My.Resources.Y
  25.  
  26.         For count = 1 To 8
  27.             y = y + b
  28.             x = x + a
  29.             If x >= x_Max - 150 Then a = -1
  30.             If x <= 0 Then a = 1
  31.             If y >= y_Max - 150 Then b = -1
  32.             If y <= 0 Then b = 1
  33.  
  34.             Call Form_press(KeyAscii)
  35.             Call Form1_KeyPress(a, AscW)
  36.             e.Graphics.DrawImage(letter(count), x, y, 150, 150)
  37.             For i = 0 To 1000000
  38.  
  39.             Next
  40.             e.Graphics.DrawImage(My.Resources.Empty, x, y, 151, 151)
  41.  
  42.         Next
  43.  
  44. End Sub
Now I need get input from keyboard, check if it is correct and return to the loop displaying another letter or if it was wrong input to come back to the same place where I left the loop.

And another question: my flying image is fine displayed but time to time it is flickering, how to make it smooth?

Thanks masters.

BTW I use VB 2008 express
Dec 29 '07 #4

Expert 5K+
P: 8,434
Nice idea, Andreig. :)

However, I would question one or two things about your method of implementing the idea.

For a start, I don't believe the Paint method is the correct place to do this. It probably should be driven by a Timer instead.

Secondly, if that For i = 0 To 1000000 is being used to slow things down, it's a really bad idea. These sort of delay loops (I think it's referred to as "software timing" or something) used to be quite common. But these days they are generally more trouble than they're worth. Each time you upgrade the computer, or possibly even when a Windows Update is installed, the timing can change. That "one to a million" loop might suddenly start taking ten times as long. Or in some cases, a "smarter" compiler might see that the loop does nothing and simply skip over it, reducing the delay time to a millionth of a second or something.

These days, you should either invoke a "real" (that is, hardware-related) delay mechanism. Or for preference, if you only want to do something ten times a second for example, you just use a timer to call it ten time a second. You see, another reason why delay loops like this are considered poor form is that they can tie up the CPU doing huge amounts of nothing.

Of course, these are all things you probably should consider if working professionally as a programmer. All that aside though, I suppose what you really want now is just some way to get it working. From what you've said, the animation seems to be working (though a bit flickery), but you're not sure how to detect the keypress. Since I use a much older version of VB, the technical details are likely to be quite different. But I can offer some general suggestions.
  • Set the form to handle all keypresses itself before allowing any controls to receive them. In VB6, this is done by setting the form's KeyPreview property to True. Don't know about your version.
  • I would create a form-level (or global) variable to hold the details of the key that was pressed. In VB6 I would just use an Integer or something to hold the ASCII value. Not sure about your version - I believe the .Net versions of VB deal with the keyboard somewhat differently.
  • In the form's KeyPress (or KeyDown) event, record what key was pressed by storing the details in your new variable.
  • During your animation, periodically check the value in your new variable, to see whether something has been recorded there since you last checked.
  • Note that in VB6 (not sure about VB 2008), the delay loop would have to include a DoEvents statement. This statement instructs VB to stop hogging the processor, and allow Windows to go handle other important functions such as reading the keyboard, updating the display and so on.

Well, I hope that's some help, anyway.
Dec 31 '07 #5

P: 7
Thanks Killer for your description and I will do it for sure.
Can you please give me examples how to fix this problem with pressed keys?
so:
  1. In what place of my code I have to put "Me.KeyPreview = True"
  2. Creating:
    Private Sub Form1_KeyPress(ByVal KeyAscii As Integer)

    End Sub
  3. "In the form's KeyPress (or KeyDown) event, record what key was pressed by storing the details in your new variable" - sorry, have noooo clue.
  4. "During your animation, periodically check the value in your new variable, to see whether something has been recorded there since you last checked."
    - you mean something like:
    call Form1_KeyPress(KeyAscii )?
  5. "to include a DoEvents statement" in what place and how to include it?
You see I am a total idiot in it.
Actually I am a software tester and want to put my nose a little bit in programming, thanks.
Dec 31 '07 #6

Expert 5K+
P: 8,434
Thanks Killer for your description and I will do it for sure.
Can you please give me examples how to fix this problem with pressed keys? ...
Being inexperienced doesn't make you an idiot. :)

Let's see, to take your points in order...
  1. I wouldn't do it in your code at all. Just set the property yourself in the IDE (Integrated Design Environment).
  2. VB will create the appropriate event procedure "skeleton" for you, so you can just put in the actual code. The declaration you showed (Form1_KeyPress) looks to me like VB6 format, and is probably not correct for VB 2008. You need to consult the documentation for how to create an event procedure. It'll be pretty simple.
  3. All I meant was, whatever details are provided to the event procedure to indicate the key pressed (in VB6, this would be KeyAscii As Integer) you should copy into a form-level variable of the same type. You might want to read up on variable "scope". It's a very fundamental and important concept.
  4. No, you're not getting the whole event-driven concept I think. You don't need to call the keypress event code, it happens when the user presses a key.
    What you are likely to have here is a couple of more or less independent routines - one running each time a Paint event happens (or better still, each time a timer fires) and another which runs each time the user presses a key. The KeyPress code will just make a note of it in a variable, so the other routine can check it.
    At the point where you want to know whether a key has been pressed, just look at the variable which was set in point 3.
  5. I don't know whether DoEvents is still relevant or not, in VB 2008. The point is that, in VB6 at least, if your code is looping around doing stuff continuously, it doesn't allow time for Windows to go and do all its regular housekeeping stuff like checking the keyboard, updating the display and so on. That's why things sometimes stop half-drawn or take a while to appear on-screen, if the system is busy. Executing a DoEvents statement simply tells Windows "ok, I'll take a breather for a moment while you go check on things". It might be best to ignore this for now, and we can go into it further, if it turns out to be necessary.
Well, gotta go! It's after 7pm, on New Year's Eve! :-D

Talk to you next year...
Dec 31 '07 #7

Expert 100+
P: 446
Hi
Try 'DoEvents'

I haven't followed your code closely because your programming capability seems to surpass my own but when I had a similar problem calling 'DoEvents' did it for me. (Using Access and VBA)

I had a loop that was reading the COM port for digital data and wanted it to be interrupted to 'Stop' or 'Save Reading' etc. Putting the DoEvents as the last line before the end of the loop allowed other button presses to be detected.

Best wishes

Sorry Killer42, I did not notice you had already suggested this
Dec 31 '07 #8

daniel aristidou
100+
P: 491
Since you have the express version of VB 2008, did you also get the updated MSDN library?
It is very useful, as long as you understand the terminology they use (quite different form VB6).
I believe it has a large section on keypress events.
Dec 31 '07 #9

Expert 100+
P: 487
As killer pointed. It will be better to use the draw command in key press event.

You have to include System.Drawing in your Class
And
Expand|Select|Wrap|Line Numbers
  1. 'In Class Module Decleration part
  2. private Pen blackPen = new Pen(Color.Black, 2)
  3. 'pnlDraw is the frame or panel control from tool box
  4. private Graphic g = new pnlDraw.CreateGraphics()
  5.  
  6. 'Move All your code in form_Paint() to Form_KeyDown() or form_keyPress()
  7. g.DrawImage(letter(count), x, y, 150, 150)
Dec 31 '07 #10

Expert 5K+
P: 8,434
...Sorry Killer42, I did not notice you had already suggested this
No problem. It's always good to get multiple viewpoints.
Jan 1 '08 #11

Expert 5K+
P: 8,434
As killer pointed. It will be better to use the draw command in key press event.
Actually, I believe I recommended doing the drawing from a timer, not from the keypress.
Jan 1 '08 #12

Post your reply

Sign in to post your reply or Sign up for a free account.