Parfois, un seul clic suffit pour lancer l’application. Mais parfois, le temps de démarrage est plus long que
prévu, une ou deux secondes, et l’utilisateur peut alors avoir le sentiment que le programme s’est figé et
que quelque chose s’est mal passé. Ceci peut être évité en réduisant le temps jusqu’à ce que la première
fenêtre s’affiche, qui s’appelle l’écran de démarrage.

Pour ce faire, toutes les actions de préparation du programme pour le travail sont effectuées après
l’affichage de l’écran de démarrage. Et l’économiseur d’écran lui-même devient la frontière séparant la vie
quotidienne grise d’un utilisateur Windows du monde imaginaire de votre application.

Partie visuelle

L’écran de démarrage est la carte de visite de l’application. Il n’y a pas de règles uniformes pour sa
conception et ne peut pas l’être. Et s’il est nécessaire de respecter certaines règles et conventions lors de la conception de la conception de l’application principale, alors lors de l’affichage de l’écran de démarrage, vous pouvez vous permettre de montrer au maximum vos talents créatifs : utilisez des palettes lumineuses ou du noir et des croquis blancs, ajoutez de l’animation ou rendez l’économiseur d’écran translucide, refusez à partir d’une forme rectangulaire. Mais, si vous êtes habitué à la retenue et à l’utilisation économe des ressources, je peux vous proposer une solution qui utilise des scripts et un fichier image pour sa mise en œuvre.

Un écran de démarrage

L’image du dossier Images\Logo est utilisée comme image d’arrière-plan et le nom de l’application s’affiche en arrière-plan. Le titre a une ombre noire qui améliore la lisibilité du texte. Le numéro de version du programme est affiché dans le coin inférieur gauche. Étant donné que le temps d’initialisation de l’application dépend des performances de l’ordinateur, il est souhaitable d’afficher l’écran de démarrage
pendant la durée spécifiée dans le paramètre, mais pas plus.

Scénarios

La fonction Splash_Create() est utilisée pour créer un formulaire splash. Il renvoie vers le formulaire créé en conséquence. Les paramètres de création sont déplacés vers des constantes.

const
  SPLASH_LOGO_WIDTH = 350; // Largeur de l'image
  SPLASH_LOGO_HEIGHT = 169; // Hauteur de l'image
  SPLASH_BORDER = 2; // Epaisseur du cadre autour de l'image
  SPLASH_BORDER_COLOR = clBlack; // Couleur de la bordure
  SPLASH_FILE_NAME = 'Images\Logo\logo_350x169.jpg'; // fichier d'image d'arrière-plan
  SPLASH_FONT_SIZE = 28; // taille de la police du titre
  SPLASH_FONT_COLOR = clWhite; // Couleur du titre
  SPLASH_SHADOW_COLOR = clBlack; // Couleur de l'ombre
  SPLASH_VER_FONT_SIZE = 11; // Taille de police pour la version
  SPLASH_VER_FONT_COLOR = clWhite; // Couleur de la police des versions
  SPLASH_DELAY_MIN = 2000 ; // durée d'affichage minimale de l'écran de démarrage ;
  // autres constantes du projet
  APP_NAME = 'Intro' ; // Nom du projet
  APP_VERSION = '1.0' ; // version du projet
  LABEL_SHADOW_SHIFT_DEF = 2 ; // décalage d'ombre par défaut
  SX_SHADOW = '_Shadow' ; // ombre 
  APP_NAME = 'Splash' ; // Nom du projet
  APP_VERSION = '1.0' ; // Version du projet

function Splash_Create:TForm;
var
  tmpImage:TImage;
  tmpLabel:TLabel;
  tmpImageFileName:string;
begin
  Result := TForm.Create(Application);
  with Result do
  begin
    Width := SPLASH_LOGO_WIDTH + SPLASH_BORDER*2;
    Height := SPLASH_LOGO_HEIGHT + SPLASH_BORDER*2;
    BorderStyle := bsNone;
    Position := poScreenCenter;
    Color := SPLASH_BORDER_COLOR;
    StyleElements := 0;
  end;
  // On ajoute une image
  tmpImage := TImage.Create(Result);
  with tmpImage do
  begin
    Parent := Result;
    Width := SPLASH_LOGO_WIDTH;
    Height := SPLASH_LOGO_HEIGHT;
    Top := SPLASH_BORDER;
    Left := SPLASH_BORDER;
    tmpImageFileName := ExtractFilePath(Application.ExeName)+SPLASH_FILE_NAME;
    if not FileExists(tmpImageFileName) then
      RaiseException('Splash_Create() Не найден файл '+tmpImageFileName)
    else
     Picture.LoadFromFile(tmpImageFileName);
  end;
  // On ajoute un titre
  tmpLabel := TLabel.Create(Result);
  with tmpLabel do
  begin
    Name := 'AppName';
    Parent := Result;
    Top := 0;
    Left := 0;
    Autosize := False;
    Width := Result.ClientWidth;
    Height := Result.ClientHeight;
    Alignment := taCenter;
    Layout := tlCenter;
    WordWrap := True;
    StyleElements := 0;
    Caption := APP_NAME;
    Font.Size := SPLASH_FONT_SIZE;
    Font.Color := SPLASH_FONT_COLOR
  end;
  Label_AddShadow( tmpLabel, SPLASH_SHADOW_COLOR ); // On ajoute une ombre
  // On ajoute le numéro de version
  tmpLabel := TLabel.Create(Result);
  with tmpLabel do
  begin
    Name := 'AppVer';
    Parent := Result;
    Caption := APP_VERSION;
    StyleElements := 0;
    Font.Size := SPLASH_VER_FONT_SIZE;
    Font.Color := SPLASH_VER_FONT_COLOR;
    Left := Height div 2;
    Top := Result.ClientHeight - Height - (Height div 2);
  end;
  Label_AddShadow( tmpLabel, SPLASH_SHADOW_COLOR, 1 ); // On ajoute d'une ombre
end;

Langage du code : Delphi (delphi)

Regardons-le attentivement. La ligne 63 appelle la procédure Label_AddShadow(), qui ajoute une ombre au texte spécifié.

L’ombre est une copie exacte du composant de l’étiquette, généralement avec une couleur de texte noire (toute couleur spécifiée, plus foncée que la principale). Il est situé avec un léger décalage derrière la marque donnée. Pour des raisons inconnues, MVDB ne prend pas en charge la méthode Assign() pour le composant TLabel, j’ai donc dû écrire un tas de code pour en obtenir une copie :

procedure Label_AddShadow( ALabel:TLabel; AColor:TColor = 0; AShift: integer = 0 );
var
  tmpLabel:TLabel;
begin
  if AShift = 0 then // si le décalage de l'ombre n'est pas spécifié, alors on prend la valeur par défaut
     AShift := LABEL_SHADOW_SHIFT_DEF;
  tmpLabel := TLabel.Create( ALabel.Owner );
  // tmpLabel.Assign( ALabel ); // Malheureusement, cette méthode ne fonctionne pas dans MVDB, vous devrez donc copier toutes les propriétés manuellement....
  // Tout ce qui suit peut être remplacé par une seule commande Assign, mais cela ne fonctionne pas dans MVD...
  tmpLabel.Name := ALabel.Name + SX_SHADOW;
  tmpLabel.Caption := ALabel.Caption;
  tmpLabel.AutoSize := ALabel.AutoSize;
  tmpLabel.Width := ALabel.Width;
  tmpLabel.Height := ALabel.Height;
  tmpLabel.Anchors := ALabel.Anchors;
  tmpLabel.Font := ALabel.Font;
  tmpLabel.StyleElements := ALabel.StyleElements;
  tmpLabel.Alignment := ALabel.Alignment;
  tmpLabel.Layout := ALabel.Layout;
  tmpLabel.WordWrap := ALabel.WordWrap;
  // Définit le décalage de l'ombre
  tmpLabel.Top := ALabel.Top + AShift;
  tmpLabel.Left := ALabel.Left + AShift;
  // Définit la couleur de l'ombre
  tmpLabel.Font.Color := AColor;
  ALabel.BringToFront; // Place le cartouche devant l'ombre
end;
Langage du code : Delphi (delphi)

Initialisation et démarrage

Avant que le formulaire principal de l’application frmMain (son nom est marqué en rouge sur l’onglet du concepteur visuel) ne s’affiche, l’événement OnShow se produit, que nous utiliserons pour créer et afficher l’écran de démarrage, ainsi que pour effectuer des actions pour initialiser l’application.

procedure frmMain_OnShow (Sender: TObject; Action: string);
// Affiche le formulaire principal
begin
  // afficher l'écran de démarrage
  App_Splash_Start;
end;Langage du code : Delphi (delphi)

Pour initialiser l’application avec l’écran de démarrage, la procédure App_Splash_Start() est appelée, dans
laquelle le formulaire de démarrage est créé et affiché, puis la procédure d’initialisation de l’application
App_Start() est appelée. Après son achèvement, le temps passé à l’initialisation est mesuré et, s’il ne
dépasse pas celui spécifié, un délai est ajouté exactement si longtemps que le temps total d’affichage de
l’écran de démarrage correspond à celui spécifié dans la constante SPLASH_DELAY_MIN. Après cela,
l’écran de démarrage est détruit, puis le formulaire principal frmMain s’affiche.

procedure App_Splash_Start;
// Initialisation avec écran de démarrage
var
  tmpForm:TForm;
  tmpStartTime: TTime;
  tmpSleepTime: integer;
begin
  tmpForm := Splash_Create;
  tmpForm.Show;
  Application.ProcessMessages;
  tmpStartTime := Time();
  App_Start;
  // Délai garanti, mais pas plus que spécifié dans SPLASH_DELAY_MIN
  tmpSleepTime := SPLASH_DELAY_MIN - Trunc( (Time() - tmpStartTime)*24*60*60*1000 );
  if tmpSleepTime > 0 then
    Sleep(tmpSleepTime);
  tmpForm.Close;
  tmpForm.Free;
end;Langage du code : Delphi (delphi)

Dans App_Start(), les sous-systèmes de l’application sont initialisés : gestion des images des boutons, des
styles, des raccourcis clavier, etc.

procedure App_Start; 
// Lance l'application
begin
  // Il ne devrait y avoir aucune initialisation ici, ce qui peut prendre beaucoup de temps
end;Langage du code : Delphi (delphi)

Ainsi, dans l’ensemble de base, il y aura deux procédures d’initialisation : avec l’écran de démarrage et sans celui-ci. Cela permettra une flexibilité dans le choix de la solution optimale. Pour les applications légères, vous pouvez appeler App_Start(), et si l’initialisation est longue, il est préférable d’utiliser
App_Splash_Start();

Si vous souhaitez utiliser le splash statique créé dans le concepteur visuel My Visual Database, modifiez App_Splash_Start() pour appeler votre formulaire frmSplash statique dessus :

procedure App_Splash_Start;
// initialisation avec écran de démarrage
var
  tmpStartTime: TTime;
  tmpSleepTime: integer;
begin
  frmSplash.Show;
  Application.ProcessMessages;
  tmpStartTime := Time();
  App_Start;
  // Délai garanti, mais pas plus que spécifié dans SPLASH_DELAY_MIN
  tmpSleepTime := SPLASH_DELAY_MIN - Trunc( (Time() - tmpStartTime)*24*60*60*1000 );
  if tmpSleepTime > 0 then
    Sleep(tmpSleepTime);
  frmSplash.Hide;
end;Langage du code : Delphi (delphi)

Liens

Traduction : Yann Yvnec

Épilogue

Malheureusement, la solution proposée n’est pas efficace à 100%, et dans certains cas, le délai entre le clic sur l’icône de lancement de l’application dans l’explorateur du système d’exploitation et l’apparition du splash screen peut être de plusieurs secondes. Pourquoi cela arrive-t-il? Pour répondre à cette question, vous devez analyser la séquence des événements et les horaires.

  1. Cliquez sur l’icône de l’application dans l’explorateur
  2. Chargement d’une application en mémoire
  3. Création de formulaires de service d’application
  4. Lecture du fichier forms.xml et création de formulaires de demande personnalisés
  5. Démarrage de la section Début Fin. dans le fichier script.pas et d’autres modules.
  6. Si le système de droits intégré est utilisé, le formulaire d’autorisation intégré s’affiche
  7. Connexion à la base de données.
  8. Connexion des données aux composants visuels.
  9. Affichage du formulaire principal de l’application

Malgré la taille solide du fichier exécutable (19 Mo), la plupart du temps n’est pas consacré à le charger en mémoire, mais à créer des formulaires utilisateur (st. 4) et à connecter des données à des composants visuels (st. 8). En déplaçant la création et l’affichage du formulaire d’écran de démarrage à l’étape 5, ce délai peut être éliminé, mais il n’est pas possible de faire face à l’étape 4. Et avec un grand nombre de formulaires et de composants sur les formulaires, le temps de création peut être quelques secondes, ce que j’observe dans certains de mes projets.

Je vois trois façons de réduire le temps de retard de l’écran de démarrage.

Application autonome

Une solution simple qui nécessite la mise en œuvre de deux dossiers : le dossier principal du projet et le dossier du projet de démarrage (starter). Malgré l’encombrement (la solution comprendra deux exécutables identiques de 19Mo chacun plus un tas de fichiers de service pour chaque projet), elle fait face assez efficacement à la tâche : l’application de démarrage ne contient qu’un seul formulaire (splash screen), démarre rapidement et démarre l’application principale. Et après avoir détecté l’affichage du formulaire de l’application principale, il s’autodétruit.

Formulaires dynamiques

Une solution difficile en termes de mise en œuvre et de développement du projet, qui implique la création programmatique de formulaires, ce qui réduit l’efficacité de l’environnement de développement visuel, le transformant en un environnement non visuel. En pratique, vous pouvez combiner la création visuelle et programmatique du formulaire et des composants, en mettant en œuvre des solutions standard répétitives à l’aide d’un script.

Raffinement de My Visual Database

Pour ce faire, vous devez ajouter la possibilité d’écrire un gestionnaire à un événement qui se produit avant de créer des formulaires utilisateur personnalisés dans MVDB. Mais pour le moment, le développement du projet est suspendu pour une durée indéterminée.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *