2011-12-13 25 views
5

lo que tengo que hacer es algo como esto:Paso de una clase como un parámetro de un procedimiento en Delphi XE

procedure A(type_of_form); 
var form: TForm; 
begin 
    form := type_of_form.Create(application); 
    form.showmodal; 
    freeandnil(form); 
end; 

Hice esto para cada forma creada dinámicamente:

form1 := TForm1.Create(application); 
form1.showmodal; 
freeandnil(form1); 

Lo que lo hará dentro del procedimiento A es más complejo, pero el problema reside en cómo hacer que la creación de la forma sea algo general. Quizás algo con @operador ... realmente no lo sé.

¡Gracias por cualquier sugerencia!

Respuesta

6
procedure Test(AMyFormClass: TFormClass); 
var 
form: TForm; 
begin 
    form := AMyFormClass.Create(Application); // you can use nil if you Free it in here 
    try 
    form.ShowModal; 
    finally 
    form.Release; // generally better than Free for a Form 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    Test(TForm2); 
end; 
+0

'form.Free' está bien allí. Vale la pena señalar que esto solo funciona si el constructor del formulario reemplaza al constructor 'TForm'. –

+0

@David, ¿está diciendo que esto no funcionará si el constructor se llama Crear, con parámetros coincidentes, si oculta el constructor descendiente? –

+2

@Marcus Eso es correcto. Necesita usar constructores virtuales para obtener instanciación a través de la referencia de clase para trabajar. De lo contrario, terminará con un 'TMyForm' cada vez, independientemente de lo que esté en la referencia de clase. –

3

Lo que estamos pidiendo es básicamente lo TApplication.CreateForm() hace, por ejemplo:

Application.CreateForm(TForm1, form1); 
form1.ShowModal; 
FreeAndNil(form1); 

Puede imitar que sin llamar TAppliction.CreateForm() así:

procedure A(AClassType: TFormClass); 
var 
    form: TForm; 
begin 
    form := AClassType.Create(Application); 
    try 
    form.ShowModal; 
    finally 
    FreeAndNil(form); 
    end; 
end; 

... 

begin 
    A(TForm1); 
end; 
+0

Sí ... el código es similar al otro (y similar al método CreateForm) ... jeje ... ¡nunca me di cuenta! – Speaker

+0

Solo otra pregunta ... ¿cuál es la mejor forma de liberar formularios? Form.release? o FreeAndNil (Formulario) cada vez que utilizo FreeAndNil ... pero ... – Speaker

+2

'TForm.Release()' está destinado a ser utilizado solamente cuando el formulario debe liberarse desde el interior de uno de sus eventos manejadores. El modo libre se retrasa hasta que el control regrese al ciclo de mensaje principal para asegurarse de que TForm no esté siendo utilizado por nada. Si sabe que el TForm ya no se usa (como es el caso en esta situación), puede llamar a 'Free()' inmediatamente. 'FreeAndNil()' es excesivo para un uso tan simple de una variable local como este ejemplo. No es necesario anular un puntero que ya no se usará. –

Cuestiones relacionadas