Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Pablo Reyes
PReyes@excite.com
El Rinconcito de Delphi
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
end.
Prestemos atención a todo lo que dice Form1. Por un lado está la declaración de la clase
del formulario, es decir, de la clase TForm1. Por otro la declaración de la variable
Form1 del tipo TForm1. Si modificamos el nombre del formulario, es decir, el valor de
su propiedad Name el nombre de la clase y el de la variable también cambiarán. Para
que no queden dudas: si cambiamos el valor de la propiedad Name de este formulario a,
por ejemplo, FRMPrueba, el nombre de la clase cambiará a TFRMPrueba y el nombre
de la variable a FRMPrueba. Este comportamiento puede ser un poco confuso. Parece
como si entre el valor de la propiedad Name, el nombre de la clase del formulario y el
nombre de la variable hubiera una relación muy estrecha. Pues bien, no la hay. Delphi
hace estos cambios para que nos resulte más fácil trabajar con el formulario pero la
realidad demuestra que no hay ninguna relación entre estos tres elementos.
Vamos a hacer un ejemplo para comprobar lo que acabo de decir. Crear un proyecto
nuevo. Para ello seleccionar del menú File | New | Application. Añadir al formulario
principal los siguientes componentes:
• De la página Standard, un Label, un Edit y dos Button.
El formulario debería verse así:
Application.CreateForm(TForm1, Form1);
Se encarga de crear una instancia de la clase TForm1 y asignar una referencia al objeto
creado en la variable Form1. Ambos elementos, es decir, la clase TForm1 y la variable
Form1 están declarados en la unidad Unit1, incluida en la cláusula uses del proyecto.
Hagamos un pequeño experimento. Añadir al formulario principal el siguiente
componente:
• De la página Standard, un Button.
Asignarle a su propiedad Caption el valor "Form1A". Ahora vamos a declarar una
variable llamada Form1A del tipo TForm1, o sea, el formulario. El código es el
siguiente:
var
Form1: TForm1;
Form1A: TForm1;
Form1.Name := Edit1.Text;
Hubiéramos utilizado la palabra reservada Self, el código hubiera tenido efecto sobre el
objeto en el cual lo ejecutamos y no sobre el objeto al cual hace referencia la variable
utilizada. Vamos a cambiar el código y a ejecutar el proyecto para comprobar todo esto.
Ahora bien, ¿qué pasa si hacemos clic más de una vez sobre el Button "Nuevo"?
El código del evento OnClick se encarga de crear una nueva instancia de la clase
TForm1 y de asignar una referencia al objeto creado en la variable Form1A. Pues bien,
cada vez que hacemos clic en el Button "Nuevo" creamos un nuevo formulario TForm1.
¿Qué pasa con el anterior?
No pasa nada. Sólo que sigue existiendo en memoria pero perdimos toda referencia al
mismo. En la variable Form1A sólo mantenemos una referencia al último formulario
creado. Sin embargo el código sigue funcionando porque tiene efecto sobre el objeto en
el cual lo ejecutamos.
Hacer clic en el BitButton tiene el mismo efector que cerrar el formulario desde el botón
de Windows. Cada vez que un formulario se cierra se dispara el evento OnClose. En
este evento podemos indicarle a Delphi que queremos que haga al cerrar el formulario.
Esto lo hacemos a través del parámetro Action al que le podemos asignar uno de los
siguientes valores:
• caNone: Delphi no hace nada. Es una forma de evitar que el usuario cierre el
formulario desde el botón de Windows.
• caHide: el formulario se oculta.
• caFree: el formulario se destruye.
• caMinimize: el formulario se minimiza.
Como dije antes, la acción por defecto es caHide. Vamos a modificar el evento OnClose
del segundo formulario para que al cerrarlo se destruya. El código es el siguiente:
Desde el punto de vista visual no hay ninguna diferencia. Pero podemos estar seguros
de que al cerrarlo el formulario se ha destruido. Vamos a comprobarlo. Añadir el
siguiente componente al formulario principal:
• De la página Additional, un BitButton.
Escribir el siguiente código para el evento OnClick del nuevo BitButton:
Antes de crear una instancia de TForm2 nos aseguramos que la variable Form2 sea igual
a nil. De esta forma podemos garantizar que sólo habrá una instancia de la clase
TForm2. Este código es muy utilizado en aplicaciones Delphi. Aún cuando sólo
ocultemos el formulario Form2 el resultado será siempre el correcto. Si ocultamos el
formulario Form2 haciendo clic en el BitButton no se disparará el evento OnClose por
lo que el formulario no se destruirá y por lo tanto tampoco se disparará el evento
OnDestroy por lo que la variable Form2 tendrá un valor distinto de nil.
Destruyendo formularios
Tenemos varias formas de destruir un formulario. Una de ellas acabamos de verla en el
ejemplo anterior. También podemos destruir un formulario llamado directamente al
método destructor, es decir, al método Destroy. Sin embargo esta no es la forma más
segura ya que si la variable que utilizamos para hacer referencia al objeto en realidad
está haciendo referencia a un objeto que no existe la llamada al método Destroy
generará un mensaje de error. Para evitar este problema debemos llamar al método
Free. El método Free es más seguro que el método Destroy ya que antes de llamar al
método Destroy verifica que la referencia al objeto sea válida.
Si destruimos explícitamente un formulario no debemos olvidarnos de asignarle el valor
nil a la variable que lo referencia. Vamos a destruir explícitamente el formulario Form2.
Modificar el código del evento OnClick del SpeedButton del formulario principal para
que se vea así: