Простой вариант: в цикл вставить вызов Application.ProcessMessages, тогда программа хоть со скрипом (в зависимости от длительности итерации цикла) будет реагировать на действия пользователя.
Сложный вариант: действительно оформить цикл как отдельный поток и сделать ассинхронный вызов, т.е. программа запускает поток, потом по таймеру проверяет, закончился ли поток. Простой вариант реализации:
Поток, в отдельном модуле:
Код:
unit WrkThread;
interface
type
TMyThread = class(TThread)
private
FIsRunning : Boolean;
FParam : String; // Какие-то данные для потока
public
procedure Execute; override;
property IsRunning : Boolean read FIsRunning;
property Param : String read FParam write FParam;
end;
implementation
procedure TMyThread.Execute;
begin
FIsRunning := True;
Try
For I := 1 To 4094 Do // Твой цикл
Begin
If Terminated Then Break; // Для того, что бы можно было прервать поток
// Далее твой код
End;
Finally
FIsRunning := False;
End;
end.
А теперь вызов:
Код:
type
TForm1 = class(TForm)
private
T : TMyThread; // В OnCreate или в конструкторе присвоить Nil
// В деструкторе или в OnDestroy уничтожить если <> Nil
end;
...
procedure TForm1.Button1Click(Sender : TObject);
begin
If T = Nil Then T := TMyThread.Create(True);
If T.IsRunning Then ShowMessage('Поток уже работает!')
Else
Begin
T.Param := 'aaa'; // передали данные потоку
T.Resume; // запускаем поток
Timer1.Enabled := True; // Запускаем таймер для проверки состояния потока
End;
end;
procedure Timer1Timer(Sender : TObject);
begin
If T = Nil Then Timer1.Enabled := False // Защита
Else
If Not T.IsRunning Then // Поток закончился
Begin
Timer1.Enabled := False; // выключаем таймер
FreeAndNil(T); // Удаляем поток, что бы не болтался
ShowMessage('Поток завершился');
End;
end;
Это грубый пример, просто что бы показать как это все работает.