I use yield inside loops to avoid application freezing by applying
if (ctr % interval)=0 then yield.
but sometimes the process inside the loop could take long time, like in some loops interval could be 1000 and it is ok and in some other loops even 10 is not ok.
So is there a way to let the application execute the Yield when necessary only.
I tried Lost Focus and Gain Focus and timer but none of them worked.
An alternative is to make the loop code be driven by a Timer Event in an Accept loop. This link is to a hand coded one in the Boxsoft Invoice Example TestDev APP you can download and use:
Below I’ll try to paste the code, it is cut from a few places:
RecordsBefore LONG
RecordsAfter LONG
ToDoRecords LONG
RecordNo LONG
Progress:Thermometer LONG
Progress:New LONG
RecordsPerCycle LONG
ProgressFACTOR REAL
ProgressWindow WINDOW('Add Test CustomerCompany'),AT(,,142,59),FONT('Segoe UI',9,,FONT:regular),DOUBLE,CENTER,GRAY,MDI
PROGRESS,AT(15,15,111,12),USE(Progress:Thermometer),RANGE(0,25)
STRING(''),AT(0,3,141,10),USE(?Progress:UserString),CENTER
STRING(''),AT(0,30,141,10),USE(?Progress:PctText),CENTER
BUTTON('Cancel'),AT(46,42,49,15),USE(?Progress:Cancel),SKIP
END
CODE
...
AddTestDataRtn ROUTINE
?Progress:UserString{PROP:Text}='Add ' & ToDoRecords
ProgressFACTOR = ?Progress:Thermometer{PROP:RangeHigh} / ToDoRecords
RecordsPerCycle = 25
RecordNo=0
0{PROP:Timer}=1
AL: ACCEPT
CASE EVENT()
OF EVENT:Timer
LOOP RecordsPerCycle TIMES
IF RecordNo >= ToDoRecords THEN BREAK AL: .
RecordNo += 1
DO AddOneRtn
END
!Update the window slows things so only do it when the % changes 1 segment, in this case 1 of 25
Progress:New = RecordNo * ProgressFACTOR
IF Progress:Thermometer < Progress:New THEN
CHANGE(?Progress:Thermometer,Progress:New)
?Progress:PctText{PROP:Text}=RecordNo &' done'
END
ELSE
IF ACCEPTED() = ?Progress:Cancel THEN
IF Message('Cancel Process?','Add Test Data',ICON:Cross, |
'Cancel|Continue',2)=1 THEN BREAK.
END
END !Case Event
END !Accept
0{PROP:Timer}=0
tm1=clock() ! Initialize the variable tm1 with the current clock time.
loop
!........... My Long Process
if clock() >= tm1+100*30 ! Check if 30 seconds have passed since the last time tm1 was set.
yield
display(?list1)
tm1=clock() ! Set tm1 to the current clock time.
end
end