I'm having a little trouble with a loop. When the user clicks the start button, it is supposed to draw a series of lines until the user clicks stop or it hits the far "wall".
It does stop when it hits the edge, but the outside input doesn't seem to be getting through. I threw in a DoEvents statement at the beginning of the loop, but still no luck.
I figure it's just something dumb, but any help would be greatly appreciated. Thanks.
Private Sub cmdStart_Click()
If cmdStart.Caption = "&Start" Then
Dim Drawing As Boolean
Drawing = True
cmdStart.Caption = "&Stop"
Do While Drawing = True And cmdStart.Caption = "&Stop"
DoEvents
DoEvents
LineY1 = 30 * Cos(LineX / 10)
LineY2 = 30 * Cos(LineX / 15)
If chkLine1.Value = 1 Then Dot StartX + LineX, StartY + LineY1, vbRed
If chkLine2.Value = 1 Then Dot StartX + LineX, StartY + LineY2, vbYellow
If chkResult.Value = 1 Then Dot StartX + LineX, StartY + LineY1 + LineY2, &H80FF&
LineX = LineX + 1
If LineX > picWave.ScaleWidth Then
Drawing = False
Exit Do
End If
If Not Drawing Then Exit Do
Loop
Else
Drawing = False
cmdStart.Caption = "&Start"
End If
End Sub
Hopefully you can make sense of that. I really need the loop to run but still allow my user input, so those check boxes actually do something.
Um, I think I was unclear. The loop does exit when line hits the wall; that part works fine. The problem is I want the loop to allow user input while it is executing, so that the user can cancel the loop whenever they want to.
Oh, and I knew I didn't need the double check, but I put it there because nothing else was working.
I encountered a similar problem once, but what it was was there was a lag in the picture drawing commands and the actual picture
update. So, when I selected a button to trigger a control variable to stop the picture processing, it appeared that my picture processing kept going for a while, then it stopped. Now, my picture drawing procedure did not have a self stop check built in, so it did stop when the trigger changed, it just took a while.
So, in essence, I think your procedure kills itself, but the picture is still refreshing, so you think it still is active, and when you press the button to stop it, it's too late.
Just as a test, throw in a msgbox command where your button triggers the stop.
Change:
Drawing = False
cmdStart.Caption = "&Start"
End If
to:
Drawing = False
cmdStart.Caption = "&Start"
msgbox "Well, your Trigger activated, anyway"
End If
I did what you said, and the msgbox popped up, but not until the loop had ended 5 seconds later because it exited itself when the drawing hit the wall.
I decided to try it a few more times and sometimes the msgbox would pop up a second after I clicked the button and actually end the loop, sometimes it would wait 2 seconds then end the loop, sometimes not at all. I'm looking for pretty much instantaneous reaction, as would happen normally. (By normally, I mean if the loop weren't running).
I think I'm going to try putting the drawing in a sub and having to different buttons.
Last edited by DarkJedi9; Jun 25th, 2001 at 09:02 AM.
If you guys (and girls) wanted to have something looping in the backgroung and still allow user input, how would you do it? I've already tried a timer, which works but too slowly, so don't bother with that unless you know how to make them work faster.
Dot is a simple function that takes a point and then draws a three by three square of the given color around it. Basically a setpixel function that sets a bigger pixel.
StartX, StartY are public in the form module, with StartX being 0 and StartY being half of the pixels scaleheight. They basically set the origin of the waves (that's what I'm drawing).
LineX, LineY1, and LineY2 are also public in the form module. LineX is the current X position of the three waves I'm drawing. They all use the same X coordinate and it is incremented by 1 each time through the loop. LineY1 and LineY2 are the Y coordinates (in relation to my origin, not 0,0) of first two waves. They are found with a couple of slightly different sin(LineX) statements. The third wave gets its Y coordinate from the sum of LineY1 and LineY2.
try it duncan-style: dont put all the code into your button event procedure but rather make the event procedure call the drawing one.
(If all else fails try making two buttons on top of each other for a test to make isolating the problem easier and make one button visible and active while the other is not - THAT shouldn't make a difference to the above approach but sometimes VB does things that it shouldn't )
Dim StartX As Long
Dim StartY As Long
Private Sub cmdStart_Click()
If cmdStart.Caption = "&Start" Then
Call picWave_Click
Dim Drawing As Boolean
Drawing = True
cmdStart.Caption = "&Stop"
Do While Drawing = True And cmdStart.Caption = "&Stop"
DoEvents
DoEvents
LineY1 = 30 * Cos(LineX / 10)
LineY2 = 30 * Cos(LineX / 15)
If chkLine1.Value = 1 Then Dot StartX + LineX, StartY + LineY1, vbRed
If chkLine2.Value = 1 Then Dot StartX + LineX, StartY + LineY2, vbYellow
If chkResult.Value = 1 Then Dot StartX + LineX, StartY + LineY1 + LineY2, &H80FF&
LineX = LineX + 1
If LineX > picWave.ScaleWidth Then
Drawing = False
Exit Do
End If
If Not Drawing Then Exit Do
Loop
Else
Drawing = False
cmdStart.Caption = "&Start"
End If
End Sub
Private Sub Form_Load()
StartX = 0
StartY = picWave.ScaleHeight \ 2
End Sub
Private Sub Dot(ByVal MY_X As Long, ByVal MY_Y As Long, ByVal MY_C As Long)
picWave.DrawWidth = 3
picWave.PSet (MY_X, MY_Y), MY_C
Form1.Caption = StartX & " " & picWave.ScaleWidth
DoEvents
End Sub
Private Sub picWave_Click()
picWave.Cls
StartX = 0
StartY = picWave.ScaleHeight \ 2
End Sub
I don't do anything with the picWave_Click, although from the looks of it, that shouldn't change much, and your picture came out fine, so I'd say you pretty much got it.
Oh, and my dot worked differently, it actually set nine pixels, but yours works better when I try it (less gaps) so I'll go with that!
Last edited by DarkJedi9; Jun 25th, 2001 at 10:53 AM.
Yeah, that's what mine does. The higher the frame rate, the faster the drawing, and the slower the response, but it works well at about 30 fps, which is good enough for me.