Lo primero es permitir que la "parada" se produzca. Mientras ejecutas un bucle, el resto de la aplicación queda congelada, así que no podríamos indicarle que parase de ninguna manera, ni pulsando un botón, ni una tecla, etc ... así que tenemos que dejar "respirar" a la aplicación. Esto podemos hacerlo de 2 maneras diferentes: usando threads o metiendo dentro del bucle la función "Application.Processmessages".
Yo para un bucle que se tiene que ejecutar "indefinidamente", o por lo menos durante un largo periodo de tiempo, prefiero usar un thread. Este correría de forma paralela al resto de la aplicación. Dentro del thread haría algo como esto:
De esta manera cuando quisiera finalizar el bucle solo tendría que llamar al método "Terminate" del TThread, y el se encargara de poner a TRUE la propiedad Terminated.
Por ejemplo:
Código Delphi
[-]
MiThread:= TMiThread.Create;
MiThread.FreeOnTerminate:= TRUE;
ShowMessage('Pulsa aceptar para finalizar');
MiThread.Terminate;
Donde TMiThread seria una clase descendiente de TThread.