by Stephan Grieger - Independent Developer
This simple little application was written to provide some sort of visual feedback to the user to inform them that the application is actually still running.
The problem was that the application needed to process over 8 million records. The progress bar would move every 1 percent or so. However, each percent represented 80,000 records. As a result, the progress bar took some time before it incremented.
Something else was needed to inform the user that the application had not failed.
Placing a label on the screen which counted up the records processed turned out to be less than satisfactory. The problem was that to refresh the screen, you needed to do a DoEvents. This then slowed the system down by around 50%.
The answer then, was to have a timer control on the form which would do something.
When I was playing around with Java, one of the examples was a spinning globe. They had also included a GIF file of the globe in all its states. So, there was the answer. Basically, just what Microsoft do in Internet Explorer - good enough for MS, good enough for SG, that's what I always say!
So, I had the solution - but how to make the globe rotate?
My first attempt basically had a picture within a picture. The picture containing the globe would be moved up and down according to the frame that needed to be displayed. This, though it worked, caused a lot of screen flickering and looked a little less than cool.
So, I figured that I could use LockWindowUpdate to stop the annoying flicker. However, this only caused the screen to flicker even more, and caused some very real problems when minimised.
So, having exhausted my normal shortcut hacks, the only other solution was then to do it properly.
The code contained in the example available for download is fairly straightforward. However, I feel that at least some explanations are required.
Basically we have two picture boxes, and take the picture contained in the second picture box and create a copy of it in memory. We need to do this otherwise when we do the StretchBlt, you will see the windows desktop copied to the picture box rather than all the globes.
Naturally, on form load we have to call CreateCompatibleDC, and we need to delete that DC on form unload, but otherwise this little routine is about all there is to it.
In the timer control, we now work out how wide and high the target box is and copy the image in Picture2 to it. If you don't require that the image be stretched, then use the BitBlt function instead.
Private Sub Timer1_Timer() Dim PicH As Integer Dim PicW As Integer Static CurrentFrame As Integer If CurrentFrame > 2205 Then CurrentFrame = 0 Call SelectObject(ShadowDC&, Picture1.Picture) PicH = Picture2.Height / Screen.TwipsPerPixelY PicW = Picture2.Width / Screen.TwipsPerPixelX Call StretchBlt(Picture2.hdc, 0, 0, PicW, PicH, ShadowDC, 0, CurrentFrame, 115, 105, &HCC0020) CurrentFrame = CurrentFrame + 105 End Sub
In the timer control, we now work out how wide and high the target box is and copy the image in Picture2 to it.
If you do not require that the image be stretched, then just use the BitBlt function instead :
Call BitBlt(Picture2.hdc, 0, 0, 115, 105, ShaddowDC, 0, CurrentFrame, &HCC0020)This a great technique, I think. It allows the user to feel something's happening, but really doesn't get in the way of the code at all. Enjoy.