28 marzo 2008

El objeto Application

Todas las aplicaciones Win32 que se crean con Delphi tienen definido un objeto global accesible desde cualquier formulario o unidad llamado Application, de la clase TApplication, el cual esta definido dentro de la unidad Forms. Este objeto se encarga de encapsular todo lo referente a nuestra aplicación, evitando el tener que procesar el envío y recepción de mensajes como ocurre cuando se programa en C/C++ mediante las funciones PeekMessage y SendMessage.

De hecho, si miramos la unidad DPR de cualquier proyecto de Delphi podemos ver como el objeto Application se incializa, después llama al formulario principal y posteriormente comienza la ejecución de la aplicación mediante el método Run:

program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

Este código fuente cambia dependiendo de las preferencias que tengamos a través del menú Project -> Options (pestaña Forms). Todos los formularios que pongamos en la sección Auto-create forms serán los que se creen después de Application.Initialize.

Windows funciona internamente como un buzón donde van llegando mensajes y los va procesando en el orden de llegada, consiguiendo así el efecto de multitarea, aunque internamente sólo puede procesar un mensaje a la vez (menos en los últimos sistemas con procesador de dos o más núcleos).

El objeto Application nos abstrae de toda esta complejidad interna y se encarga de controlar todos los eventos que se producen en nuestra aplicación. Si queremos modificar el comportamiento de nuestra aplicación para ciertos eventos, tenemos en la pestaña Additional el componente ApplicationEvents que podemos colocar en el formulario principal de nuestra aplicación, controlando así eventos tan comunes como OnActivate, OnRestore, OnMessage, etc.

Por ejemplo, se puede utilizar el evento OnIdle para que nuestro programa realice cálculos complejos en segundo plano cuando el procesador esté desocupado, aprovechando al máximo el rendimiento de nuestro PC. También se puede utilizar el evento OnMessage para interceptar mensajes de Windows que incluso Delphi no tiene definidos en el objeto Application.

MOSTRANDO MENSAJES

Esta es una de las funciones que más se suelen utilizar del objeto Application:

function MessageBox( const Text, Caption: PChar; Flags: Longint = MB_OK ): Integer;

Esta función muestra al usuario un mensaje dentro de un cuadro de dialogo. Para mostrar un mensaje informativo sería así:

Application.MessageBox( 'Mensaje informativo.', 'Atención',
MB_ICONINFORMATION );

se vería así:


Otro mensaje sería para informar al usuario que se ha interrumpido un proceso:

Application.MessageBox( 'No ha rellenado el nombre del proveedor.',
'Acceso denegado', MB_ICONSTOP );

este sería el resultado:


También se puede hacer una pregunta al usuario por si desea realizar algo:

if Application.MessageBox( '¿Desea continuar?', 'Guardando factura',
MB_ICONQUESTION OR MB_YESNO ) = ID_YES then
....

este cuadro de diálogo tendría dos botones:

El parámetro flags de esta función permite que aparezcan los siguientes botones:

MB_ABORTRETRYIGNORE Anular, Reintentar y Omitir.
MB_OK Aceptar (por defecto).
MB_OKCANCEL Aceptar y Cancelar.
MB_RETRYCANCEL Reintentar y Cancelar.
MB_YESNO Si y No.
MB_YESNOCANCEL Si, No y Cancelar.

Entre los posibles mensajes que devuelve esta función (según lo que hagamos con flags) tenemos:

Constante Valor numérico Resultado
--------- -------------- ---------
IDOK 1 El usuario ha pulsado Aceptar.
IDCANCEL 2 El usuario ha pulsado Cancelar.
IDABORT 3 El usuario ha pulsado Abortar.
IDRETRY 4 El usuario ha pulsado Reintentar.
IDIGNORE 5 El usuario ha pulsado Ignorar.
IDYES 6 El usuario ha pulsado Si.
IDNO 7 El usuario ha pulsado No.

CONTROLANDO EL ESTADO DE LA APLICACIÓN

Tenemos los siguientes procedimientos disponibles para controlar el estado global de la aplicación:

procedure Minimize;

Este procedimiento minimiza la aplicación en la barra de tareas. Es importante tener bien claro cual es el formulario principal de la aplicación, ya que si minimizamos otra ventana provocará un efecto no deseado: se minimiza en la esquina inferior izquierda del escritorio. Para evitar esto siempre tenemos que procurar que el formulario que se pueda minimizar sea siempre el formulario principal. Si no fuera así, entonces recomiendo que toda la aplicación sea de tipo MDI.

procedure Restore;

Vuelve a mostrar la ventana principal de la aplicación si ha sido minimizada por el usuario o por el propio programa con el método Minimize.

procedure BringToFront;

Este procedimiento enfoca de nuevo nuestra aplicación superponiendo la ventana principal de nuestra aplicación a otras aplicaciones que se estén visualizando en este momento en Windows. Puede ser interesante cuando tenemos que informar al usuario de algún evento que se ha producido en nuestra aplicación (como hacen los antivirus).

procedure CreateForm( FormClass: TFormClass; var Reference );

Este es otro de los procedimientos más utilizados por el objeto Application. Crea el formulario que le pasemos como parámetro. El primer parámetro es la variable de la instancia que se va a crear y el segundo es la clase de la variable. Por ejemplo:

Application.CreateForm( FCliente, TFCliente );

procedure Terminate;

Hay que estar muy seguro para llamar a este procedimiento, ya que cierra toda la aplicación por la fuerza. Si tenemos algún formulario que haya instanciado algunos objetos que no ha liberado de memoria se podría quedar memoria desperdiciada en todo Windows.

procedure ProcessMessages;

Es importante llamar a este procedimiento cuando estamos haciendo un proceso largo que gasta bastante procesador, ya que si no lo hacemos así el usuario tiene la sensación de que la aplicación se ha colgado. Hay que llamar a este procedimiento en cada iteración del bucle.

LEYENDO DATOS DE NUESTRA APLICACION

El objeto Application también es muy útil para obtener información. Veamos que funciones pueden utilizarse para esto:

property Active: Boolean;

Esta propiedad nos dice si la aplicación esta activa y enfocada.

property ExeName: string;

Nos devuelve la ruta y nombre completo de donde se está ejecutando nuestra aplicación. Si nos interesa saber sólo la ruta se podría hacer esto:

ExtractFilePath( Application.ExeName );

property MainForm: TForm;

Nos devuelve la referencia al formulario principal de la aplicación. Si el formulario principal cambiara, no haría falta modificar el código de nuevo.

property ShowMainForm: Boolean;

Si desactivamos esta propiedad, cuando arranque el programa por primera vez no mostrará la ventana principal. Esto puede ser útil para mostrar la típica ventana de presentación antes de mostrar la pantalla principal. También puede utilizarse si vamos a crear un control de usuarios con clave de acceso y necesitamos que no muestre la ventana principal antes de que se haya validado el usuario.

property Title: string;

Modificando esta propiedad podemos cambiar en tiempo de ejecución el título de nuestra aplicación según su estado (se ve sobre todo cuando está minimizada en la barra de tareas).

property Handle: HWND;

Un handle es un identificador único que Windows da a todas las aplicaciones y ventanas que crea. Este handle (que en realidad es un valor numérico) es muy utilizado por funciones de la API de Windows. Por ello, esta propiedad es muy interesante para leer el handle de nuestra aplicación (cada vez que se ejecuta una aplicación Windows le da un handle distinto).

Aunque el objeto Application tiene más funciones y propiedades creo que hemos cubierto aquí las más importantes.


Pruebas realizadas en Delphi 7.

Publicidad