exit loop by pressing a key and come back

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Andreig
    New Member
    • Dec 2007
    • 7

    exit loop by pressing a key and come back

    Gentlemen I cannot figure out the following:
    I have a loop in[CODE=vbnet]Private Sub Form1_Paint(ByV al sender As Object, ByVal e As System.Windows. Forms.PaintEven tArgs) Handles Me.Paint[/CODE]

    Pressing a key I am checking what key was pressed and come back to the loop.

    Thanks for help
    Last edited by Killer42; Dec 29 '07, 12:52 PM.
  • creative1
    Contributor
    • Sep 2007
    • 274

    #2
    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.

    [CODE=vb]Private Sub Form_KeyPress(K eyAscii As Integer)
    msgbox KeyAscii
    End Sub[/CODE]
    Last edited by Killer42; Dec 29 '07, 12:53 PM.

    Comment

    • Killer42
      Recognized Expert Expert
      • Oct 2006
      • 8429

      #3
      Originally posted by Andreig
      ...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.

      Comment

      • Andreig
        New Member
        • Dec 2007
        • 7

        #4
        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:
        [CODE=vbnet]Private Sub Form1_Paint(ByV al sender As Object, ByVal e As System.Windows. Forms.PaintEven tArgs) Handles Me.Paint

        'flying baloon
        Dim y_Max As Integer = Me.Size.Height( )
        Dim x_Max As Integer = Me.Size.Width()
        Dim x As Integer = x_Max / 2 - x_Max / 4
        Dim y As Integer = y_Max - 150
        Dim letter(26) As Image
        Dim count As Integer
        Dim a As Integer = 1
        Dim b As Integer = -1
        'Dim z As Integer
        Dim KeyAscii As Integer
        Dim KeyChar As Integer

        letter(1) = My.Resources.E
        letter(2) = My.Resources.I
        letter(3) = My.Resources.O
        letter(4) = My.Resources.Q
        letter(5) = My.Resources.R
        letter(6) = My.Resources.T
        letter(7) = My.Resources.U
        letter(8) = My.Resources.W
        letter(9) = My.Resources.Y

        For count = 1 To 8
        y = y + b
        x = x + a
        If x >= x_Max - 150 Then a = -1
        If x <= 0 Then a = 1
        If y >= y_Max - 150 Then b = -1
        If y <= 0 Then b = 1

        Call Form_press(KeyA scii)
        Call Form1_KeyPress( a, AscW)
        e.Graphics.Draw Image(letter(co unt), x, y, 150, 150)
        For i = 0 To 1000000

        Next
        e.Graphics.Draw Image(My.Resour ces.Empty, x, y, 151, 151)

        Next

        End Sub[/CODE]

        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
        Last edited by Killer42; Dec 31 '07, 12:07 AM.

        Comment

        • Killer42
          Recognized Expert Expert
          • Oct 2006
          • 8429

          #5
          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.

          Comment

          • Andreig
            New Member
            • Dec 2007
            • 7

            #6
            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.KeyPrev iew = 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.
            Last edited by Killer42; Dec 31 '07, 08:04 AM.

            Comment

            • Killer42
              Recognized Expert Expert
              • Oct 2006
              • 8429

              #7
              Originally posted by Andreig
              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...

              Comment

              • sierra7
                Recognized Expert Contributor
                • Sep 2007
                • 446

                #8
                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
                Last edited by sierra7; Dec 31 '07, 11:26 AM. Reason: Just read Killer42's post in more detail

                Comment

                • daniel aristidou
                  Contributor
                  • Aug 2007
                  • 494

                  #9
                  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.
                  Last edited by Killer42; Jan 1 '08, 11:17 AM.

                  Comment

                  • CyberSoftHari
                    Recognized Expert Contributor
                    • Sep 2007
                    • 488

                    #10
                    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
                    [CODE=vbnet]'In Class Module Decleration part
                    private Pen blackPen = new Pen(Color.Black , 2)
                    'pnlDraw is the frame or panel control from tool box
                    private Graphic g = new pnlDraw.CreateG raphics()

                    'Move All your code in form_Paint() to Form_KeyDown() or form_keyPress()
                    g.DrawImage(let ter(count), x, y, 150, 150)[/CODE]

                    Comment

                    • Killer42
                      Recognized Expert Expert
                      • Oct 2006
                      • 8429

                      #11
                      Originally posted by sierra7
                      ...Sorry Killer42, I did not notice you had already suggested this
                      No problem. It's always good to get multiple viewpoints.

                      Comment

                      • Killer42
                        Recognized Expert Expert
                        • Oct 2006
                        • 8429

                        #12
                        Originally posted by CyberSoftHari
                        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.

                        Comment

                        Working...