IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Ouverture d'une TForm selon valeur d'un String


Sujet :

Delphi

  1. #1
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut Ouverture d'une TForm selon valeur d'un String
    Bonjour à toutes et à tous

    Petit question.
    Est-il possible d'ouvrire une Form selon la valeur d'un variable de type String ?

    Je m'explique.
    Admettons que ma variable est ce genre de valeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MyVariable := 'Materiel';
    // ou
    MyVariable := 'Voiture';
    // ou
    MyVariable := 'Location';
    Peut-on ouvrir la form qui s'y rattache ? de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      LaForm := TF?????.Create(Self) do
      Try
          Showmodal;
      Finally
          Release;
      End;
    Le TF?????, j'imagine bien que je pourrais faire un Case of, mais ne peut-on pas avoir un record de TForm prémorisé ? ou un truc du genre ?

    Je précise que les forms sont obligatoirement tous différentes.

    Merci.

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    voici un moyen simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    procedure TMainForm.FormCreate(Sender: TObject);
    begin
      RegisterClass(TMateriel);
      RegisterClass(TVoiture);
      RegisterClass(TLocation);
    end;
     
    function TMainForm.GetFormByName(const AName: string): TForm;
    begin
      Result := TForm(GetClass('T' + AName).NewInstance);
      Result.Create(Self);
    end;
     
    procedure TMainForm1.Button1Click(Sender: TObject);
    var
      Form: TForm;
    begin
      Form := GetFormByName('Materiel');
    end;
    voila
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    voici un moyen simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    procedure TMainForm.FormCreate(Sender: TObject);
    begin
      RegisterClass(TMateriel);
      RegisterClass(TVoiture);
      RegisterClass(TLocation);
    end;
     
    function TMainForm.GetFormByName(const AName: string): TForm;
    begin
      Result := TForm(GetClass('T' + AName).NewInstance);
      Result.Create(Self);
    end;
     
    procedure TMainForm1.Button1Click(Sender: TObject);
    var
      Form: TForm;
    begin
      Form := GetFormByName('Materiel');
    end;
    voila
    Superbe.

    Mais, car il y a un mais...

    Aujourd'hui, j'ouvre une form principal de départ, sur cette Form principal, j'en ouvre une seconde (que j'appelerai FormVisu) où se trouve les boutons, là je clique sur un bouton [modifier] par exemple et j'utilise ta proposition. bien.

    Mais la form Visu au moment de l'ouvrir, je sais pertinament que je n'ouvrirais pas la suite, à l'aide des boutons qu'une seul et unique form (form de saisie).
    A chaque fois que j'ouvre la form Visu je peux être soit sur la liste s des véhicules soit sur la liste des matériels, etc.. mais jamais les 3 ou 2 en même temps, donc quand j'ouvre ma form de saisie (a l'aide de ta proposition) puis-je faire ceci :

    Dans la form principal
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    procedure TFPrincipal.FichierClick(Sender: TObject);
    Var
      CaptionFichier: String;
    begin
      if (Sender is TMenuItem) then
      begin
                 // xTable peut avoir la valeur 
                 // Materiel, Vehicule, Location
                 // xTable est déclarér en public sur formVisu
       With TFormVisu.Create(Self) do
       begin
        Try
           xTable := (hint du TMenuItem cliqué); // J'envoi le nom de la table à FormVisu utilisé pour DBGrid
     
     
    // comment ici pouvoir envoyer que la fiche de saisie est lier à xTable
    // sachant que je n'ai forcément qu'un choix à faire parmis 3
           RegisterClass(T??? xTable ???);
     
           ShowModal;
        Finally
          release;
        end;
    // ....
     
    end;

    Dans la form visu quand je vais cliquer sur le bouton créer par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function TFormVisu.GetFormByName(const AName: string): TForm;
    begin
      Result := TForm(GetClass('T' + AName).NewInstance);
      Result.Create(Self);
    end;
    
    procedure FormVisu.Button1Click(Sender: TObject);
    var
      Form: TForm;
    begin
      Form := GetFormByName(xTable); // POSSIBLE ???
    end;
    Merci

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Normalement le RegisterClass n'est pas obligatoire, il est fait automatiquement parce que la Form est associé à une Ressource DFM !
    A Vérifier !

    Je n'arrive pas à comprendre ton second problème !
    Tu veux qu'une seule instance par classe de Form ?

    Tu stockes tes objets dans une TStringList triés, si IndexOf trouve le nom, tu renvoie l'instance, dans la cas contraire tu créés une nouvelle instance et tu l'ajoute à la liste !

    Tu peux aussi parcourir les Components de la MainForm qui énumèrent toutes les fenêtres qui l'ont comme Owner
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    ... Tu peux aussi parcourir les Components de la MainForm qui énumèrent toutes les fenêtres qui l'ont comme Owner
    Non, les forms sont créées à la volée, il n'existe pas avant le clique sur un bouton.

    Citation Envoyé par ShaiLeTroll Voir le message
    Normalement le RegisterClass n'est pas obligatoire, il est fait automatiquement parce que la Form est associé à une Ressource DFM !
    A Vérifier !
    ... Si tu le dis ....

    Citation Envoyé par ShaiLeTroll Voir le message
    Tu stockes tes objets dans une TStringList triés, si IndexOf trouve le nom, tu renvoie l'instance, dans la cas contraire tu créés une nouvelle instance et tu l'ajoute à la liste !
    ???? hummm... et cela se traduit comment ? je n'ai j'amais gérezr ce type d'objet dans un TStringlist ou autre TList.

    Citation Envoyé par ShaiLeTroll Voir le message
    Je n'arrive pas à comprendre ton second problème !
    Tu veux qu'une seule instance par classe de Form ?
    A l'écrit pas évident à s'expliquer. Je fais refaire de mon mieux

    J'ai un TMenu avec des items (véhicule, voiture, location) dans le hint de chacun de ces items j'ai respectivement (vehicule, voiture, location) ... si si si il y à une différence le caractère accentué et le souligné que j'aurais pas... bref.
    Quand je clique sur un des items, je récupére donc le Hint qui en fait est le nom de ma Table que je devrais afficher.

    Donc je clique par exemple sur l'item voiture, là une TFORM s'ouvre avec un DBGRID et 4 boutons (y a plein d'autre chose mais on s'en fou), au create de cette form j'envoi le nom de la table qui est donc le hint pour le DBGRID.

    d'où :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure TFPrincipal.FichierClick(Sender: TObject);
    Var
      CaptionFichier: String;
    begin
      if (Sender is TMenuItem) then
      begin
       With TFormVisu.Create(Self) do
       begin
        Try
           xTable := (hint du TMenuItem cliqué); // pour le DBGrid (enfin le Qry et source)
           ShowModal;
        Finally
    // ...
    Ensuite je sais pertinament que l'utilisateur va cliquer sur un des 4 boutons respectivement [Créer] / [Modifier] / [SUPPRIMER] / [COPIER] et que cela sera lié à la table donc ici voiture.
    Si il clique sur [Créer] j'ouvre la TForm voiture (qui est forcément différente des autre Tform) et il créé sa bagnole.
    Fini il ferme tous

    Donc le file conducteur est xTable, comment faire pour optimiser mon code ?
    En fait, je n'ai pas besoin de préparer avec un registerClass l'ensemble des fenêtres de saisie, puisque je le saurais tout au début au moment du clique sur le HINT.

    Le but étant de simplifié le code.

    J'espère avoir été plus claire.

    Merci pour vos idées.

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 426
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 426
    Points : 1 326
    Points
    1 326
    Par défaut
    @ BuzzLeclaire, et si tu utilisais la propriété "Tag" ?

    Pour mes différents Skins c'est ce que je fais avec la variable I Integer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    i:=Tcomponent(sender).tag;
    @+,

    Cincap

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Le register class est nécessaire pour les fiches (sous D7 en tout cas) car elles ne sont jamais crée par le DFM mais c'est elles qui chargent les DFM

    Pour ce qui est de ta seconde question elle est bidon si je puis me permettre

    Le problème: tu veux pouvoir créer une fiche d'après son nom

    La solution: il te faut une information qui lie le nom à la classe

    La méthode 1: tu peux créer un TStringList qui associe les noms et les classes en te creusant la tête sur comment faire fonctionner le tout

    La méthode que je préconise : utiliser RegisterClass qui fait déjà tout ça et GetClass qui va avec

    Les 3 appels à RegisterClass() ne font rien d'autre que d'associer le type à son nom, soit EXACTEMENT ce que tu cherches

    après ton histoire de xTable c'est juste de savoir à quel moment tu vas instancier la classe retournée par GetClass, au moment du clic sur un bouton ou avant, peu importe.

    EDIT: au fait si c'est une question d'optimisation tu colles en effet un entier dans Tag et tu fais un case dessus au lieu de t'emm... avec des string
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par BuzzLeclaire Voir le message

    Citation Envoyé par ShaiLeTroll Voir le message
    Normalement le RegisterClass n'est pas obligatoire, il est fait automatiquement parce que la Form est associé à une Ressource DFM !
    A Vérifier !
    ... Si tu le dis ....
    Je le dis mais c'est une erreur, j'ai tellement l'habitude d'utiliser mes propres objets que j'oublie que certains incluent des mécanismes automatiques (dont le RegisterClass parce que j'utilise bcp ce genre de comportement), donc oui il faut bien le faire explicitement

    J'aurais du lire mais signature avant !

    Sinon, pour ce genre de chose j'utilise aussi un type numérique, le Tag pour le stockage dans le menu que je converti en Enumération

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    type
      TSaisieFormClass = class of TSaisieForm; // un type ancêtre pour regrouper des trucs standard comme Edit, View, ... à surcharger si besoin ...
      TSaisieFormClassType = (sfcVoiture, Location, sfcAutre)
     
    const
      FORM_CLASSES : array[TSaisieFormClassType] of TSaisieFormClass =
        (TSaisieVoitureForm, TSaisieLocationForm, TSaisieAutreForm);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (Ord(Low(TSaisieFormClassType)) <= Menu.Tag) and (Menu.Tag <= Ord(high(TSaisieFormClassType))) then 
      Form := FORM_CLASSES[TSaisieFormClassType(Menu.Tag)].Create(Self)
    else
      raise ESaisieFormError.Create(...);
    Si tu n'aime pas le Tag, reste la possibilité de faire via
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    I := TypInfo.GetEnumValue(TypeInfo(TSaisieFormClassType), 'sfc' + Menu.Hint)

    le RegisterClass a un défaut, c'est que l'on ne trouve pas facilement l'endroit ou la classe est utilisé, voir jamais car le seul uses peut être dans le DPR et nulle part ailleurs
    le tableau force un uses explicite et permet de plus facilement retrouver ses petits
    ce n'est que mon avis, j'utilise les deux méthodes selon l'humeur
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Merci à vous.

    Comme le Dit Paul, pourquoi se faire chi** avec des strings ou l'utilisation compliquer d'instanciation !!!

    En fait sachez que j'utilisais avant le tag et je faisais un Case restait à savoir que 0 = tel form à ouvrir 1 = tel autre etc... rien de bien compliqué...

    Mais cela me permet surtout d'apprendre grace à vous des méthodes que je n'aurais jamais imaginé... comme le type ancêtre TSaisieFormClass = class of TSaisieForm; de Shell ou le TForm(GetClass('T' + AName).NewInstance); de Paul.

    Vous avez largement répondu à mon besoin et je vous remercie.



+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. nombre de lignes dans une table selon valeur
    Par halimux dans le forum Requêtes
    Réponses: 2
    Dernier message: 29/01/2014, 10h55
  2. Réponses: 9
    Dernier message: 12/04/2012, 17h03
  3. Sélectionner une colonne selon valeur inexistante ?
    Par ctobini dans le forum Requêtes
    Réponses: 2
    Dernier message: 25/02/2008, 15h49
  4. interdire une selection dans une liste selon valeur
    Par polianita dans le forum Access
    Réponses: 3
    Dernier message: 08/09/2006, 17h19
  5. Réponses: 3
    Dernier message: 13/06/2006, 16h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo