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 :

Comment écrire ça proprement ?


Sujet :

Delphi

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 39
    Points : 130
    Points
    130
    Par défaut Comment écrire ça proprement ?
    Bonjour à tous,

    Je vais aller droit au but. J'ai une application dont l'architecture se résume à :
    - Une TForm principale avec un menu, une toolbar etc, qui sert de conteneur
    - Une dizaine d'écrans héritant de TFrame qui viennent s'intégrer dans cette fenêtre principale

    On affiche les différents écrans via le menu de la fenêtre.


    Ce que je veux faire :
    - Disposer d'un moyen de reset l'écran en cours (le Free, puis le Create). Vider tous les champs etc ne m’intéresse pas. Je cherche un moyen générique que je peux appliquer à toutes mes frames, et éventuellement, plus globalement, à n'importe quel objet.


    Ma solution actuelle :
    - Dans la fiche de ma fenêtre principale, j'ai une variable par TFrame.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    type
      TFormMain = class(TForm)
      {...}
      end;
    var
      frameControl : TFrameControl;
      frameConfig : TFrameConfig;

    - J'ai une procedure FenetrePrincipale.resetEcran(Sender : TObject)
    Dans cette procedure, je viens tester la classe de Sender (TFrameControl, TFrameConfig ...)

    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
    procedure TFenetrePrincipale.ResetEcran(Sender: TObject);
    var
      mesClasses: TStringList;
      sourceClass: String;
    begin
      mesClasses := TStringList.Create;
      mesClasses.AddStrings(['TFrameControl', 'TFrameConfig']);
      sourceClass := (Sender as TFrame).ClassName;
     
      FreeAllFrames; //Méthode se chargeant de tenter un free sur tous mes écrans
      case mesClasses.indexOf(sourceClass) of
        0:
          PopControl;
        1:
          PopConfig;
      end;
      mesClasses.Free;
    end;
    puis en fonction de la classe de Sender, j'apelle la même procedure que pour pop simplement mon écran :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TFenetrePrincipale.popConfig;
    begin
      //Crée l'instance si besoin
      if not Assigned(frameConfig) then
        frameConfig := TFrameConfig.Create(Self);
      //Place le frame dans la fenêtre principale
      frameConfig .Parent := Self;
    end;

    Cette architecture est moche, pas modulable car ça me fait modifier ma fenêtre principale à chaque fois que je veux lui ajouter un écran. Et le nom des classes hardcodé etc ... Il me faut autre chose !

    Après pas mal d'essai, j'ai pensé à la solution suivante, est-ce réalisable ou suis-je en train d'inventer la roue carré ?
    - Ajouter à ma TFenetrePrincipale une property qui stocke l'écran affiché :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    property CurrentFrame : TFrame read FCurrentFrame write FCurrentFrame;
    - Ajouter une property qui viendrai stocker le constructeur de la dernier frame pop
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      TProcedureCreate = procedure (AControl : TWinControl);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    property LastCreate : TProcedureCreate read FLastCreate write FLastCreate;
    L'affectation à se fait lors du la méthode popConfig (par ex)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure TFenetrePrincipale.popConfig;
    begin
      //Crée l'instance si besoin
      if not Assigned(frameConfig) then
        frameConfig := TFrameConfig.Create(Self);
      //Place le frame dans la fenêtre principale
      frameConfig .Parent := Self;
      LastCreate := @TFrameConfig.Create;//Ça compile
    end;
    Comme ça je peux avoir ma procedure de resetEcran qui devient tout bêtement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CurrentFrame.Free;
    CurrentFrame := LastCreate(Self);//Ça compile pas (type incompatible entre TFrame et pointer, procedure)
    CurrentFrame.Parent := Self;


    Grâce à cette solution, je peux Free puis Create mon objet sans même connaitre sa classe. Qu'en pensez-vous ? Pourquoi ça ne compile pas ? Quelle solution auriez-vous adopté ?



    PS : J'ai pas copié collé les bouts de code, juste réécrit en plus simple, ne m'en voulez pas si j'ai oublié quelque chose

  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
    tout fait beaucoup de choses inutiles en fait

    voici un exemple sur un fiche avec une frame en dur

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    type
      TForm1 = class(TForm)
        Frame21: TFrame2;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
        procedure RecreateFrame(var AFrame: TFrame);
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      RecreateFrame(TFrame(Frame21));
    end;
     
    procedure TForm1.RecreateFrame(var AFrame: TFrame);
    type
      TFrameType = class of TFrame;
    var
      FrameType: TFrameType;
    begin
      FrameType := TFrameType(AFrame.ClassType); // récupére le type de frame
     
      AFrame.Free;  // la supprime
     
      AFrame := FrameType.Create(Self); // la recrée
      AFrame.Parent := Self;
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre éprouvé Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2005
    Messages : 765
    Points : 960
    Points
    960
    Par défaut
    J'ai déjà réalisé des applications avec chargement dynamique de frames.

    Le plus simple est de créer une frame de références contenant des appels à des méthodes virtuelles que tu surcharge dans des frames enfants !

    Cette approche simplifié grandement le code produire pour utiliser des frames...

  4. #4
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 39
    Points : 130
    Points
    130
    Par défaut
    Merci beaucoup pour vos réponses.

    der§en, j'utilise ce genre de solutions pour quelques frames qui se ressemblent beaucoup. Je ne vois pas comment ça s'applique à mon problème.

    Paul TOTH, super, c'est exactement ce que je cherchais, j'ai testé et ça marche nickel.

    Cette partie me semble un peu obscure.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    type
      TFrameType = class of TFrame;
    var
      FrameType: TFrameType;
    En effet, class of je ne vois pas bien ce que ça fait.
    Pour l'instant je n'ai vu class que dans le contexte de l'héritage : class(TFrame) par exemple.
    Mais j'ai eu beau tordre ton code dans tous les sens, pas moyen de me passer de cette partie

  5. #5
    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
    Citation Envoyé par Orionos Voir le message
    Merci beaucoup pour vos réponses.

    der§en, j'utilise ce genre de solutions pour quelques frames qui se ressemblent beaucoup. Je ne vois pas comment ça s'applique à mon problème.

    Paul TOTH, super, c'est exactement ce que je cherchais, j'ai testé et ça marche nickel.

    Cette partie me semble un peu obscure.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    type
      TFrameType = class of TFrame;
    var
      FrameType: TFrameType;
    En effet, class of je ne vois pas bien ce que ça fait.
    Pour l'instant je n'ai vu class que dans le contexte de l'héritage : class(TFrame) par exemple.
    Mais j'ai eu beau tordre ton code dans tous les sens, pas moyen de me passer de cette partie
    alors quand tu déclares "Frame1: TFrame1" tu as une variable pour une instance de TFrame1, quand tu déclares "FrameType: TFrameType" avec "FrameType = class of TFrame" tu as une variable sur un type de TFrame, par exemple TFrame1. C'est donc un niveau au dessus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    type
      TFrameType = class of TFrame;
    var
      FrameType: TFrameType;
    begin
      FrameType := TFrame1; // ou TFrame2, ...
      Frame := FrameType.Create(nil); // crée un type différent selon la valeur de FrameType
    end;
    c'est utilisé notamment par Application.CreateForm à qui on donne en paramètre un TComponentClass (class of TComponent), par exemple TForm1.

    d'ailleurs le code que j'ai donné aurait très bien pu utiliser TComponentClass à la place de TFrameType, on a juste besoin d'un type avec un constructor acceptant un Owner; c'est le cas de TComponent dont dérive TFrame.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 39
    Points : 130
    Points
    130
    Par défaut
    Merci pour ces précisions c'est bien plus clair maintenant !

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

Discussions similaires

  1. [VBA Excel] Comment écrire un code dans le ThisWorkBook ?
    Par WebPac dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 03/05/2005, 15h03
  2. Comment écrire un fichier texte au format MS-DOS ?
    Par fredfred dans le forum Langage
    Réponses: 9
    Dernier message: 20/01/2005, 09h00
  3. [VB.NET] comment écrire du texte avec opengl?
    Par ero_senin dans le forum OpenGL
    Réponses: 2
    Dernier message: 17/01/2005, 13h34
  4. [JAR] Comment écrire dans un fichier properties dans un jar
    Par Alec6 dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 05/10/2004, 15h16
  5. Comment écrire explicitement en sortie d'un job OEM ?
    Par zestrellita dans le forum Entreprise Manager
    Réponses: 11
    Dernier message: 11/03/2004, 09h36

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