Pues toma el bucle del objeto TScreen. Al contrario de lo que parece, ese objeto mantiene una lista
de todas tus ventanas creadas.
TFrmCliente(Screen.Forms[1]).Loquesea
Screen.Forms[2].Close;
Tienes varias formas:
- Programando el OncloseQuery de tal manera que al ordenar el cierre de esa ventana, se ejecuta dicho evento, que tomará las decisiones oportunas. En este caso no puedes diferenciar si el usuario cerró la ventana o es el Idle.
- Creando un procedimiento "universal" y heredando.
La idea es crear un FormBase que implemente el procedimiento de cierre. Ahora todas tus ventanas heredan de él (no es complejo), y cada uno hace lo que tenga que hacer.
Esto es lo que uso con más de 30 ventanas y es una maravilla. File -> new Form:
Código Delphi
[-]
type TBaseForm = Class(TForm)
public
procedure Cierra(...parametros); virtual;abstract;
end;
Lo guardas como "UBaseForm.pas"
Ahora abres tus ventanas, las que ya tienes en tu programa, se verán así:
Código Delphi
[-]
type TFrmCliente = class(TForm)
....
....
end;
La modificas para que quede así (a mano, vamos):
Código Delphi
[-]
uses UBaseForm;
type TFrmCliente = class(TBaseForm) <<<<<<<< Ahora hereda de nuestra ventana
....
public
procedure Cierra(... mismos parametros); override; <<<<<< declaramos la funcion y le decimos que vamos a redefinir (override) su comportamiento
....
end;
implementation
procedure TFrmCliente.Cierra(... mismos parametros); <<<<< La implementamos, claro.
begin
lo que tenga que hacer esta ventana.
end;
Ahora puedes hacer un bucle por el objeto TScreen, haciendo que cada ventana ejecute su propio código:
Código Delphi
[-]
for i:=0 to screen.FormCount-1 do
TBaseForm(Forms[i]).Cierra
En realidad, esto se llama herencia visual y se hace al revés, es decir, primero creas el BaseForm y cada vez que necesites una ventana nueva vas a File -> new -> (pestaña con el nombre de tu programa) -> elijes el TBaseForm y aceptas.
Cómo tú ya tienes todas las ventanas creadas, tienes que hacerlo a mano.
Saludos