DELPHI : Démarrer une application tantôt sur Form1 tantôt sur Form2

Soit une application avec 2 fiches :

  1. Form1
  2. Form2

  • Form1 est la fiche principale de l’application,
    • elle comporte l’ensemble des menus et la quasi totalité des procédures
  • Form1 peut ouvrir Form2, fiche secondaire pour présenter une formule simplifiée de l’interface,
    • Exemple dans ARCHIMAIL avec une fiche sans menu (ArchiBox) , toujours en avant et qui ne sert qu’au drag and drop.
  • Dans l’une des Options de Form1 je peux cocher le choix :
    • Démarrer en mode ARCHIBOX

LE PROBLÈME :


  • Si je demande à ARCHIMAIL de démarrer en mode “Caché”  (OnCreate Hide Archimail), puis de lancer ARCHIBOX (Show Archibox), j’ai une Erreur Grave d’Allocation, car comme les fiches sont créées l’une après l’autre, Afficher une fiche qui n’existe pas encore est un non sens !)
  • cela ne marche pas mieux quel que soit le niveau de la requête dans Form1
    • (On Activate, On Resize ou On Show)

LA SOLUTION :


Se fait en 2 temps :

(1)

  • Il faut intervenir directement dans le source du Projet en inversant l’ordre de création des fiches selon la valeur de la case à cocher…
    • L’accès au code source du projet se fait par le MENU de l’EDI(TEUR)
      • Projet => Voir le Source
    • Habituellement on n’intervient pas sur ce ficher qui est généré automatiquement par le compilateur , mais il s’agit d’un code Pascal comme tous les autres et programmable exactement de la même façon.
    • Le développement de mini-programmes Pascal sans interface, se fait en programmant uniquement ce fichier.

STRUCTURE DU SOURCE  de PROJET

    • Le source du projet porte le nom du projet (Ici Archimail)
    • Et commence toujours par la directive “program” à la place d’UNIT
    • Il n’y a pas de NOM de PROCÉDURE, car Program est une procédure équivalente à Main.
program archimail;

{$R *.dres}

uses

{$R *.res}

begin


end.
  • Il comporte une clause USES
    • dans laquelle sont chargées par défaut les bibliothèques fondamentales de l’application pour la gestion des fiches (VCL.Forms)
    • Et la définition des fiches,
    • Mais à laquelle on peut très bien rajouter des Bibliothèques personnelles (Ici JC32_INI qui gère la lecture des fichiers de configuration.)
  • Puis des Balises begin et end. (avec un point.)  qui délimitent le programme d’initialisation des fiches et qui comporte au moins 3 instructions :
    1. Initialize
    2. CreateForm
    3. Run

CODE COMPLET :

program archimail;

{$R *.dres}

uses
Vcl.Forms,
unit1 in 'unit1.pas' {Form1} ,
unit_drag in 'unit_drag.pas' {Form_DRAG} ,

jc32_ini;

{$R *.res}

begin
Application.Initialize;

if getbool('CASES_A_COCHER', 'chk_ArchiBox', False) = True then
Begin
  Application.CreateForm(TForm_DRAG, Form_DRAG);
  Form_DRAG.show;
  Application.CreateForm(TForm1, Form1);
  Form1.Hide;
End
else
Begin
  Application.CreateForm(TForm1, Form1);
  Form1.show;
  Application.CreateForm(TForm_DRAG, Form_DRAG);
  Form_DRAG.Hide;
End;

Application.Run;

end.
  • Les fiches n’étant encore pas créées au niveau du projet, on ne peut pas lire la valeur des choix de l’interface pour savoir quelle fiche il faut afficher en premier,
    • Il faut donc aller lire directement sur le disque l’ordre d’affichage dans le fichier de configuration (ARCHIMAIL.INI => valeur de chk_ArchiBox, section CASES_A_COCHER
    • La gestion complète des fichiers INI est développée dans la bibliothèque JC32_INI, qu’il suffit de placer dans la clause USES et que nous ne détaillerons pas ici)

ALGORITHME : 

C’est l’ordre des lignes qui définit la priorité d’affichage.

  • Si OPTION ARCHIMAIL Activée:
    1. Crée la fiche ARCHIMAIL (form1) en mode SHOW
    2. Puis crée la fiche ARCHIBOX (form2) en mode HIDE

Résultat : Archimail s’affiche car archimail est la fiche principale.

  • Si OPTION ARCHIBOX est Activée: (archimail désactivé)
    1. Crée d’abord  la fiche ARCHIBOX (form2) en mode SHOW
    2. Puis crée la fiche ARCHIMAIL (form1) en mode HIDE

Résultat : ArchiBox s’affiche car archiBox devient la fiche principale.

(2)

Le problème va survenir à la fermeture des fiches, (événement OnClose) car la fermeture d’une fiche :

  1. Déclenche l’événement CLOSE sur une fiche secondaire (la fiche se ferme) et prend le statut “cachée”) le programme reprend la main.
  2. Mais Déclenche l’événement TERMINATE sur une fiche principale (le programme se ferme, libère toutes les ressources  et ferme toute les fiches actives)
    • En clair : si Archibox s’ouvre en premier:
      • Sa fermeture va fermer l’application alors qu’on voudrait que sa fermeture affiche ARCHIMAIL et que le programme continue.
      • De plus, une fois réglé le problème précédent,  la fermeture d’Archimail (form1) considérée comme une fiche secondaire, va générer un CLOSE qui va cacher la fiche mais garder le programme en mémoire, ce qui va consommer des ressources et empercher de le relancer (puisqu’il est toujours actif)

Il faut donc reprogrammer les comportements de fermeture de form1 (vraie fiche principale même si elle s’ouvre en second) et de form2 (vraie fiche secondaire même si elle s’ouvre en premier)

Evènement OnClose :

  • Form2 
Action := caNone;
Hide;
Form1.Show;
Instruction Action
CaNone Annule la fermeture la fiche
(Cancel Action = None)
Hide cache Archibox
Form1.Show Affiche ArchiMail
  • Form1

Il suffit de terminer la procédure de fermeture par :

Application.Terminate Ferme toute les fiches
Libère toutes les ressources
Arrête le programme.

A noter :

– Que la propriété TOUJOURS EN AVANT

FormStyle := fsStayOnTop;

N’est activée que si la fiche est la fiche principale ! (donc la première ouverte)

Laisser un commentaire