Ich glaube, du hast das Arbeitsprinzip von Windows-Applikationen nicht ganz verstanden.

Die Callback Funktionen, die ein Button aufruft, oder jedes andere GUI Element, sollten immer so kurz wie moeglich gehalten werden. Denn die ganze GUI ist idR blockiert, solange diese CallBack Funktion nicht verlassen wird.

Daher sind Repeat ... Until Schleifen, die unabhaengig von der konkreten eingabe auf etwas warten, ein ganz ganz boeses NoNo. Dafuer hat man andere Mechanismen zur Verfuegung. Die Call Back Funktion ist idR nur dazu da, bestimmte Flags und Variablen deines Programms zu aendern. Was diese dann bewirken, das steht in einer anderen Routine (oder sogar in einem anderen Thread) und nicht in der GUI.

Du musst dich von der Vorstellung des sequentiellen Programmablaufes trennen. Unter Windows ist alles Message-Orientiert.

Ich mache mal ein kleines Beispiel:

Mach ein neues Formular und erzeuge ein Label, einen Button und einen Timer (Ich denke, der steht im Panel Systemkomponenten). Zudem lege eine integer Variable namens Counter in deinem Form an. Dann mach einen Doppelklick auf den Button und schreibe folgende Funktion zum Abarbeiten in das OnClickEvent

Code:
Form1.Timer1.enable := not(Form1.Timer1.enable);
Dann mache einen Doppelklick auf das Timer Objekt und gibt im OnTimerEvent folgenden Code ein:

Code:
inc(Form1.Counter);
Form1.Label1.Caption := toString(Form1.Counter);
Form1.Label1.Update;
Dann starte das Programm. Wenn du nun auf den button klickst, sollte das Label anfangen, im Sekundenrakt die Natuerlichen Zahlen sukzessiv anzuzeigen. Wenn du ein weiteres Mal auf den Button klickst, wird das Zaehlen angehalten. Ein weiterer Klick setzt das zaehlen fort. usw.

Der ganze Post ist aus der Erinnerung geschrieben, und ich glaube, ich hab das letzte Mal mit Delphi intensiv vor 5 jahren gearbeitet. Daher keine Gewaehr auf die syntaktische Richtigkeit.