The best option is to move the loop to its own workflow, so the main thread is not blocked, then you do not need to call ProcessMessages () at all.
However, if you need to loop through the main thread, you can use MsgWaitForMultipleObject () to determine when to call ProcessMessages (), i.e.:
Screen.Cursor = crHourGlass; R := FirstRecord; while R <> nil do begin { do something simple with R.Value } if MsgWaitForMultipleObjects(0, nil, False, 0, QS_ALLINPUT) = WAIT_OBJECT_0 then Application.ProcessMessages; R := R.NextRecord; end; Screen.Cursor := crDefault;
Alternatively with PeekMessage ():
var Msg: TMsg; Screen.Cursor = crHourGlass; R := FirstRecord; while R <> nil do begin { do something simple with R.Value } if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then Application.ProcessMessages; R := R.NextRecord; end; Screen.Cursor := crDefault;
Alternatively with GetQueueStatus ():
Screen.Cursor = crHourGlass; R := FirstRecord; while R <> nil do begin { do something simple with R.Value } if GetQueueStatus(QS_ALLINPUT) <> 0 then Application.ProcessMessages; R := R.NextRecord; end; Screen.Cursor := crDefault;
source share