Как выйти из цикла for по нажатию на кнопку?
Как выйти из цикла при нажатии на другую кнопку (Остановить выполнение Button1Click) при нажатии на кнопку Button2Click:
Кнопка с циклом:
procedure TForm1.Button1Click(Sender: TObject);
var
A: TStringDynArray;
X: array of TStringDynArray;
i, j: integer;
NewFileName, s: String;
begin
if not OpenDialog1.Execute then Exit;
A := TFile.ReadAllLines(OpenDialog1.FileName);
SetLength(X, Memo1.Lines.Count);
for i := Low(A) to High(A) do
for j := 0 to Memo1.Lines.Count - 1 do
begin
s := Trim(Memo1.Lines[j]);
if Copy(A[i], 1, Length(s)) = s then
begin
SetLength(X[j], Length(X[j]) + 1);
X[j, High(X[j])] := A[i];
end;
end;
for i := 0 to Memo1.Lines.Count - 1 do
begin
NewFileName := Format('%s%s.txt', [ExtractFilePath(OpenDialog1.FileName), Memo1.Lines[i]]);
if Length(X[i]) > 0 then TFile.WriteAllLines(NewFileName, X[i]);
end;
end;
Кнопка остановить:
procedure TForm2.Button2Click(Sender: TObject);
begin
// Break;
end;
Я так понимаю Break; не подходит к циклу for i ?
Ответы (1 шт):
Break прекрасно прерывает циклы, в том числе и For.
А не срабатывает прерывание потому, что пока не завершится обработчик первой кнопки, обработчик второй не будет вызван.
Как преодолеть - вынести долго исполняющийся код в отдельный поток. Это не так уж просто, если нужно обмениваться данными между основным потоком и дополнительным - а в приведённом примере всё зачем-то завязано на визуальные контролы (TMemo).
Во многих случаях можно обойтись периодической проверкой флага внутри цикла, а для обеспечения опроса второй кнопки вставить принудительную обработку сообщений (Application.ProcessMessages). Метод не рекомендуется для широкого применения - это костыль, когда нужно быстро обеспечить какую-никакую работоспособность.
for i := Low(A) to High(A) do begin
Application.ProcessMessages;
if boolFlag then Break;
...
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
boolFlag := True;
end;