Faire du nom d'un formulaire une variable

Résolu
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 - 9 janv. 2014 à 21:25
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 - 13 janv. 2014 à 09:44
J'ai un programme qui contient, en plus de l'unité principale, 3 unités qui ont toutes les 3 trois exactement la même structure, les mêmes variables et les mêmes procédures.
Chaque unité est consacrée à la description d'un bateau et contient les procédures suivantes:
PROCEDURE Afficher_l_age_du_capitaine;
PROCEDURE Afficher_l_age_du_moussaillon;
PROCEDURE Afficher_le_nom_du_capitaine, etc...

Dans l'unité principale, on demande de choisir un chiffre de 1 à 3. Ensuite voici mon programme:
IF Choix=1 then
   WITH Form1 DO
       Afficher_l_age_du_capitaine
ELSE
IF Choix=2 then
   WITH Form2 DO
       Afficher_l_age_du_capitaine
ELSE
IF Choix=3 then
   WITH Form3 DO
       Afficher_l_age_du_capitaine;


On le devine, je voudrais bien faire ça plus simplement. Des idées ?




--

9 réponses

dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
10 janv. 2014 à 07:44
case choix of
1: form1.lageducapitaine;
2: form2.lageducapitaine;
3: form3.lageducapitaine;
end;

ah j'oubliais : bonjour
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
10 janv. 2014 à 12:24
Salut, merci pour cette réponse. Mais en fait, j'ai abrégé: dans chacun des cas, il y a beaucoup d'affichage. Il faudrait donc que j'écrive:
 case choix of
 1: with form1 do
  begin
      Afficher_lageducapitaine;
      Afficher_le_nom_du_capitaine;
      Afficher_le_nom_du_bateau;
  end;
 2: with form2 do
begin
    Afficher_lageducapitaine;  etc..;
end; 
 3: with form3 do
begin
    Afficher_lageducapitaine;  etc...
end;

--
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
10 janv. 2014 à 12:28
J'ai appuyé sur "Valider" un peu trop tôt au lieu d'appuyer sur "Visualiser", je reprends.
On m'a parlé d'enfants mdi. Crois-tu que ce serait la bonne solution ?

Fredelem

--
0
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
10 janv. 2014 à 12:36
Tu peux également faire dans chaque form une procedure globale spécifique qui reroupe tout ce que tu dois faire dans la form spécifiée

exemple :
procedure TForm1.ExeForm;
begin
Afficher_lageducapitaine;
Afficher_le_nom_du_capitaine;
Afficher_le_nom_du_bateau;
....
end;

dans l'unité principale tu n'a plus que :

case choix of
1. Form1.ExeForm;
2. Form2.ExeForm;
3. Form3.ExeForm;
end;
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
10 janv. 2014 à 17:09
Exact. Mais je dois bien reconnaître que j'ai mal présenté mon problème. Dans le désir de ne dire que l'essentiel, je l'ai tellement modifié qu'on se retrouve assez loin du problème réel.

En fait, il me faut absolument trouver un moyen d'indicier mes formulaires. Comme ça, au lieu d'écrire:

case choix of
   1: form1.Presenter_le_bateau;
   2: form2.Presenter_le_bateau; 
   3: form3.Presenter_le_bateau;
end;


il me suffit d'écrire:
  Form[choix].Presenter_le_bateau;


Avec la technique mdi, c'est faisable. Au lieu de Form[choix], il me faut écrire:
With TFormBateau(Mdi_children[choix]) do Presenter_le_bateau;

Gros inconvénient: les 3 fiches-enfants créées ne peuvent pas être cachées (qui sait pourquoi ?) et elles deviennent des composants de la Form1, donc elles doivent rester à l'intérieur de Form1, ce qui est un peu gênant.

Je pense que je ne vais pas chercher plus loin. Je ne peux pas rendre les fiches invisibles mais je peux les minimiser ou les cacher en leur donnant une width égale à 0 ou en leur donnant un top égal à -3000.

Si tu vois une meilleure solution, je suis toujours preneur. Merci de toutes façons de t'être intéressé à mon pb.

Fred

Je marque le problème "résolu" si je trouve le bouton pour le faire.
--
0
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
10 janv. 2014 à 22:11
Salut,
Et en faisant comme ça :

var
  Choix: Integer;
begin
  Choix := 2;
  with TForm(Application.FindComponent('Form' + IntToStr(Choix))) do
    Presenter_le_bateau;
end;

?
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
11 janv. 2014 à 06:56
Diable, ça peut marcher ça ?

Il faut non pas TForm mais TFormBateau sinon, j'aurai le message "Presenter_le_bateau: procedure inconnue dans le type TForm".

Il faut donc que je conserve ma fiche TFormBateau et que je la duplique 3 fois non plus en créant des enfants-mdi mais en créant des formulaires normaux. Mais ces formulaires normaux resteront des composants de Form1 et je risque d'avoir le même problème: ils ne pourront pas sortir de Form1.

Bon, allez, ça ne représente pas un gros boulot d'essayer. Je tente le coup et je te dis ce que ça donne.


--
0
dubois77 Messages postés 675 Date d'inscription jeudi 17 avril 2008 Statut Membre Dernière intervention 19 février 2019 14
11 janv. 2014 à 07:34
La solution de Korgis est parfaite
Mais que vient faire TFormBateau ?
dès le départ tu faisais mention de Form1, Form2, Form3 (d'ou la solution de Korgis )
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
11 janv. 2014 à 07:39
Voilà, je reviens, ça n'a pris longtemps. J'ai enlevé à Form1 sa qualité de mère-mdi et à FormBateau sa qualité d'enfant-mdi mais je n'ai rien changé aux lignes qui fabriquent les 3 bateaux:
FormBateau1:=TFormBateau.Create(Form1);
FormBateau2:=TFormBateau.Create(Form1);
FormBateau3:=TFormBateau.Create(Form1);

Et là, la compilation bloque: on ne peut pas créer une form dans une form sans utiliser la technique mdi !

Ça valait quand même le coup d'essayer. Si ça avait marché, j'aurais souvent utilisé cette façon de faire.

J'avoue que les bateaux, c'était bidon. En fait, ce que j'écris, c'est un programme étudiant 3 lois statistiques: loi de Gauss, loi de Poisson et loi uniforme mais si j'avais dit ça au départ, ça aurait eu l'air rébarbatif, personne ne se serait approché.

Si je viens à bout de ce programme, je pourrai faire dans quelque temps un envoi sur le test du khi2 qui, j'espère, ne sera pas trop rébarbatif.
--
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
11 janv. 2014 à 11:29
Le drernier message de Dubois est arrivé pendant que je faisais mes essais et je ne l'ai vu qu'après avoir envoyé mon propre message. Je pense qu'il aura compris que, passant des lois aux bateaux, je m'étais emmêlé les pinceaux.

Mais une nouvelle idée m'est venue, toute simple: je reprends ma première version, celle où les 3 FormBateaux étaient créées normalement avec leurs trois fiches .DFM qui étaient des clones les unes des autres et dans Form1, je crée la variable:
Fbateau: Array[1..3] of FormBateau;

Puis dans FormActivate, je dis:
.   FBateau[1]:=FormBateau1;
    FBateau[2]:=FormBateau2;
    FBateau[3]:=FormBateau3;


et si j'écris:
With FBateau[1] do Showmessage(name)
,
ça marche ! Youpee, j'ai trouvé un moyen d'indicier les noms des formulaires.

Oui mais, si je veux présenter le bateau, il me faut recopier dans Form1 la structure de FormBateau de façon à pouvoir écrire:
With TFormBateau(FBateau[1]) DO Presenter_le_bateau;


et là, le compilateur me crée un problème auquel je ne m'attendais pas, il me dit "Presenter le bateau: declaration forward non satisfaite". Il n'en a pourtant pas besoin, je lui donne une structure, ça devrait lui suffire.

Enfin bon, je suis obligé d'en rester à la solution des enfants-mdi, je m'en accomoderai. Mais puisque je vois que le compilateur accepte deux déclarations de Form, je vais voir si je peux créer 2 formulaires dans la même unité, ce serait une nouvelle piste...
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
11 janv. 2014 à 12:41
Je reviens après un nouvel essai. En fait, je n'ai pas besoin de recopier dans Form1 la définition du type TFormBateau puisque cette définition est donnée dans les 3 unités-bateau.
J'ai donc essayé dans le FormActivate de l'unit1:
With TFormBateau(FBateau[1]) DO Presenter_le_bateau;

Et ça marche ! Youpee !
Du coup, j'ai un nouveau problème: pour quelle solution opter ? Avec ou sans les enfants-mdi ?
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
13 janv. 2014 à 09:44
Je reviens deux jours après. J'en ai bavé pour mettre en application ce que j'avais annoncé mais maintenant, j'ai quelque chose de très simple:

VAR MesBateaux: Array[1..3] of TFormBateau3 ;

 MesBateaux[1]:=TformBateau3[FormBateau1];
 MesBateaux[2]:=TformBateau3[FormBateau2];
 MesBateaux[3]:=TformBateau3[FormBateau3];


Et voilà, je peux écrire sans problème:
For i:=1 to 3 do
   MesBateaux[i]. Presenter_le_bateau;


Delphi est généreux avec les transtypages. J'ai essayé pour rigoler:
Showmessage(TLabel(Bouton1).name):

Et j'ai bien obtenu "Bouton1" !

Mais là, je suis obligé d'être très prudent: il faut que les 3 FormBateau restent strictement identiques. En jouant, j'ai, sans m'en apercevoir, supprimé un petit composant sur l'un des 3 bateaux et du coup, toutes ses variables étaient décalées, elles prenaient des valeurs absurdes.

Encore merci à tous les deux.

Fred
--
0
Rejoignez-nous