forms - Delphi: inicialización de la aplicación: mejores prácticas/enfoque
initialization datamodule (7)
Me encuentro con esto regularmente, y estoy buscando la mejor práctica / enfoque. Tengo una aplicación que contiene una base de datos / módulo de datos y deseo activar la base de datos / conjuntos de datos en el inicio sin tener "activo en tiempo de ejecución" establecido en verdadero en el momento del diseño (la ubicación de la base de datos varía). También ejecute una rutina web de "verificación de actualizaciones" cuando se inicia la aplicación.
Dadas las secuencias de eventos de TForm y los resultados de varias pruebas y errores, actualmente estoy usando este enfoque:
Utilizo un registro "Globals" configurado en el formulario principal para almacenar todos los vars globales, tener un elemento llamado Globals.AppInitialized (boolean) y establecerlo en False en la sección Inicialización del formulario principal.
En el evento OnShow de la forma principal (todos los formularios están creados para entonces), pruebo Globals.AppInitialized; si es falso, ejecuto mis operaciones de "Inicialización" y luego termino configurando Globals.AppInitialized: = True.
Esto parece funcionar bastante bien, pero ¿es el mejor enfoque? Buscando información de la experiencia, ideas y opiniones de otros. TIA ...
No estoy seguro de entender por qué necesitas las variables globales. Hoy escribo TODAS mis aplicaciones Delphi sin una sola variable global. Incluso cuando los usé, nunca tuve más de un par por aplicación.
Entonces quizás primero necesites pensar por qué los necesitas.
Es posible que desee interferir directamente con el origen del proyecto (archivo .dpr) después de las llamadas de creación de formularios y antes de la ejecución de la aplicación. (O incluso antes en el caso)
Así es como generalmente manejo este tipo de inicialización:
...
Application.CreateForm(TMainForm, MainForm);
...
MainForm.ApplicationLoaded; // loads options, etc..
Application.Run;
...
No sé si esto es útil, pero algunas de mis aplicaciones no tienen ningún formulario creado automáticamente, es decir, no tienen forma principal en el IDE.
El primer formulario creado con el objeto Aplicación como su propietario se convertirá automáticamente en la forma principal. Por lo tanto, solo autocrearé un módulo de datos como cargador y dejaré que este decida qué módulos de datos crear cuándo y qué formularios crear en qué orden. Este módulo de datos tiene un método StartUp y ShutDown, que se denominan "corchetes" alrededor de Application.Run en dpr. El método ShutDown le da un poco más de control sobre el proceso de apagado.
Esto puede ser útil cuando ha diseñado diferentes "formas principales" para diferentes casos de uso de su aplicación o puede usar algunos archivos de configuración para seleccionar diferentes formas principales.
Por lo general, siempre desactivo la creación automática de todas las formas, EXCEPTO para el formulario principal y posiblemente el módulo de datos principal.
Un truco que aprendí que puede hacer es agregar su módulo de datos a su proyecto, permitir que se cree automáticamente y crear ANTES de su formulario principal. Luego, cuando se crea su formulario principal, ya se habrá ejecutado onCreate for the datamodule.
Si su aplicación tiene algún código que decir, establezca el foco de un control (algo que no puede hacer en la creación, ya que es "no visible aún") luego cree un mensaje de usuario y publíquelo en el formulario en su creación. El mensaje DEBERÍA (sin garantía) procesarse tan pronto como se procese el bucle de mensajes de formularios. Por ejemplo:
const
wm_AppStarted = wm_User + 101;
type
Form1 = class(tForm)
:
procedure wmAppStarted(var Msg:tMessage); message wm_AppStarted;
end;
// in your oncreate event add the following, which should result in your wmAppStarted event firing.
PostMessage(handle,wm_AppStarted,0,0);
No puedo pensar en una sola vez que este mensaje nunca se haya procesado, pero la naturaleza de la llamada es que se agrega a la cola de mensajes, y si la cola está llena, se "quita". Solo ten en cuenta que existe un caso límite.
Realmente no hay un concepto como una "variable global" en Delphi. Todas las variables tienen un alcance para la unidad en la que se encuentran y otras unidades que usan esa unidad.
Simplemente haga que AppInitialized e Initialization sean parte de su módulo de datos. Básicamente tiene una clase (o módulo de datos) para gobernar todas sus cosas que no son UI (algo así como One-Ring, excepto no todas las malvadas y demás).
Alternativamente, usted puede:
- Llámalo desde tu pantalla de inicio.
- Hazlo durante el inicio de sesión
- Ejecute la "comprobación de actualización" en un hilo de fondo: no los fuerce a actualizar en este momento . Hazlo como Firefox.
Un truco que uso es colocar un TTimer en el formulario principal, establecer el tiempo en algo así como 300 ms, y realizar cualquier inicialización (inicio de sesión db, copias de archivos de red, etc.). Al iniciar la aplicación, aparece el formulario principal de inmediato y permite que ocurra cualquier "materialización" de inicialización. Los usuarios no inician instancias múltiples pensando "Oh ... no hice clic doble ... lo haré de nuevo ..."
Utilizo un Módulo de datos primario para verificar si la conexión de BD es correcta y, de lo contrario, mostrar un formulario de componente personalizado para configurar la conexión de db y luego carga el formulario principal:
Application.CreateForm(TDmMain, DmMain);
if DmMain.isDBConnected then
begin
Application.CreateForm(TDmVisualUtils, DmVisualUtils);
Application.CreateForm(TfrmMain, frmMain);
end;
Application.Run;