Crear componentes dinámicamente (en tiempo de ejecución)

La mayoría de las veces, cuando se programa en Delphi, no es necesario crear dinámicamente un componente. Si suelta un componente en un formulario, Delphi maneja la creación del componente automáticamente cuando se crea el formulario. Este artículo cubrirá la forma correcta de crear componentes mediante programación en tiempo de ejecución.

Creación dinámica de componentes

Hay dos formas de crear componentes dinámicamente. Una forma es hacer que un formulario (o algún otro TComponent) sea el propietario del nuevo componente. Esta es una práctica común cuando se construyen componentes compuestos donde un contenedor visual crea y posee los subcomponentes. Hacerlo asegurará que el componente recién creado se destruya cuando se destruya el componente propietario..

Para crear una instancia (objeto) de una clase, llama a su método "Crear". El constructor Crear es un método de clase, a diferencia de prácticamente todos los demás métodos que encontrará en la programación de Delphi, que son métodos de objeto.

Por ejemplo, el TComponent declara el constructor Create de la siguiente manera:

constructor Create (AOwner: TComponent); virtual;

Creación dinámica con propietarios
Aquí hay un ejemplo de creación dinámica, donde Yo es un descendiente de TComponent o TComponent (por ejemplo, una instancia de un TForm):

con TTimer.Create (Self) do
empezar
Intervalo: = 1000;
Habilitado: = Falso;
OnTimer: = MyTimerEventHandler;
final;

Creación dinámica con una llamada explícita a la libertad
La segunda forma de crear un componente es usar nulo como el dueño Tenga en cuenta que si hace esto, también debe liberar explícitamente el objeto que cree tan pronto como ya no lo necesite (o producirá una pérdida de memoria). Aquí hay un ejemplo del uso de nil como propietario:

con TTable.Create (nil) do
tratar
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Abierto;
Editar;
FieldByName ('Ocupado'). AsBoolean: = Verdadero;
Enviar;
finalmente
Gratis;
final;

Creación dinámica y referencias de objetos
Es posible mejorar los dos ejemplos anteriores asignando el resultado de la llamada Crear a una variable local del método o perteneciente a la clase. Esto es a menudo deseable cuando las referencias al componente deben usarse más tarde, o cuando los problemas de alcance potencialmente causados ​​por bloques "Con" deben evitarse. Aquí está el código de creación TTimer desde arriba, usando una variable de campo como referencia para el objeto TTimer instanciado:

FTimer: = TTimer.Create (Self);
con FTimer hacer
empezar
Intervalo: = 1000;
Habilitado: = Falso;
OnTimer: = MyInternalTimerEventHandler;
final;

En este ejemplo, "FTimer" es una variable de campo privado de la forma o contenedor visual (o lo que sea "Self"). Al acceder a la variable FTimer desde los métodos de esta clase, es una muy buena idea verificar si la referencia es válida antes de usarla. Esto se hace usando la función Asignada de Delphi:

si asignado (FTimer), entonces FTimer.Enabled: = True;

Creación dinámica y referencias de objetos sin propietarios
Una variación de esto es crear el componente sin propietario, pero mantener la referencia para su posterior destrucción. El código de construcción para el TTimer se vería así:

FTimer: = TTimer.Create (nil);
con FTimer hacer
empezar
...
final;

Y el código de destrucción (presumiblemente en el destructor del formulario) se vería así: