-
1
- #1
Olaf Doschke
Programmer
First of all you typically refresh a form via Thisform.Refresh(), but can also enforce the total repainting of the form by thisform.Cls().
Recently I did the following simple progress form and initially used Refresh, as I thought that a) would be enough and b) would be faster and more often refresh the progress bar. The real world code does more in the while loop, but for demonstration purposes this code just updating the progress bar is sufficent as repro code:
Start this as is, and the progress bar will smoothly fill up from left to right.
Now change the Cls() to Refresh() (see the comment) and let it run again. Now the bar will fill less smooth, the rectangle will grow in abrupt steps (maybe it's just on my hardware?)
This already establishes the question of why Cls() is better than Refresh(), but on top of that the behavior differs, if you don't have the ShowProgress code in a separate method.
So comment the call of the ShowProgress method in the Process Method and uncomment the lines below, which do the same. Again smooth, as Cls() is used. But now change Cls() to Refresh() again, and it stays smooth.
That's odd, isn't it?
And you can even top it off, by doing COVERAGE logging. I get more iterations with Refresh() than with Cls(), even in the case the progress bar grows abruptly. So coverage measures Refresh() to be faster than Cls(), which I would have expected in the first place. It seems Refresh() calls are only causing an event queuing in the Windows event queue and eventually be executed once the OS has time for it, while Cls() enforces a direct repaint. So far my thoughts on this.
But what influence does the separate method have, why does the progress show extremely abrupt in the case I do Refresh() instead of Cls() in the separate ShowProgress method, while coverage then still logs more iterations in the case of using Refresh() than when using Cls()?
I don't get it.
Bye, Olaf.
Recently I did the following simple progress form and initially used Refresh, as I thought that a) would be enough and b) would be faster and more often refresh the progress bar. The real world code does more in the while loop, but for demonstration purposes this code just updating the progress bar is sufficent as repro code:
Code:
PUBLIC oform1
oform1=NEWOBJECT("Progressform")
oform1.Show
RETURN
DEFINE CLASS Progressform AS form
BorderStyle = 1
Height = 40
Width = 800
AutoCenter = .T.
TitleBar = 0
AlwaysOnTop = .T.
InitialWidth = 0
ADD OBJECT shpprogress AS shape WITH ;
Top = 0, ;
Left = 0, ;
Height = 40, ;
Width = 800, ;
BorderStyle = 0, ;
BorderWidth = 0, ;
FillStyle = 0, ;
FillColor = RGB(32,192,64)
ADD OBJECT tmrstartprocess AS timer WITH ;
Enabled = .T., ;
Interval = 1, ;
Name = "tmrStartProcess"
PROCEDURE Process
Local t0, lnProgress
t0 = Seconds()
lnProgress = 0
Do While lnProgress<100
lnProgress = 100*(Seconds()-t0)/3
Thisform.ShowProgress(lnProgress)
* Thisform.shpProgress.Width = Min(Thisform.Width,Max(0,lnProgress/100 * Thisform.InitialWidth))
* Thisform.Cls()
Doevents
EndDo
EndProc
Procedure ShowProgress
Lparameters tnProgress
Thisform.shpProgress.Width = Min(Thisform.Width,Max(0,tnProgress/100 * Thisform.InitialWidth))
Thisform.Cls() && <-------------- try Thisform.Refresh() here instead
Endproc
PROCEDURE shpprogress.Init
Thisform.InitialWidth = This.Width
This.Width = 0
ENDPROC
PROCEDURE tmrstartprocess.Timer
This.Enabled = .F.
Thisform.Process()
Thisform.Release()
ENDPROC
ENDDEFINE
Start this as is, and the progress bar will smoothly fill up from left to right.
Now change the Cls() to Refresh() (see the comment) and let it run again. Now the bar will fill less smooth, the rectangle will grow in abrupt steps (maybe it's just on my hardware?)
This already establishes the question of why Cls() is better than Refresh(), but on top of that the behavior differs, if you don't have the ShowProgress code in a separate method.
So comment the call of the ShowProgress method in the Process Method and uncomment the lines below, which do the same. Again smooth, as Cls() is used. But now change Cls() to Refresh() again, and it stays smooth.
That's odd, isn't it?
And you can even top it off, by doing COVERAGE logging. I get more iterations with Refresh() than with Cls(), even in the case the progress bar grows abruptly. So coverage measures Refresh() to be faster than Cls(), which I would have expected in the first place. It seems Refresh() calls are only causing an event queuing in the Windows event queue and eventually be executed once the OS has time for it, while Cls() enforces a direct repaint. So far my thoughts on this.
But what influence does the separate method have, why does the progress show extremely abrupt in the case I do Refresh() instead of Cls() in the separate ShowProgress method, while coverage then still logs more iterations in the case of using Refresh() than when using Cls()?
I don't get it.
Bye, Olaf.