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

Langage Delphi Discussion :

Form fsMDIForm et mdiCHild!


Sujet :

Langage Delphi

  1. #1
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut Form fsMDIForm et mdiCHild!
    Bonjour Tout le monde

    J'ai une fenêtre fsMdiForm avec des boutons sur le toolbar pour créer des form de type MdiChild, à chaque fois que je clique sur un bouton il m'ouvre une nouvelle form MdiCHild, le problème c'est que je veux que lorsque je clique sur un bouton, il doit vérifier si la fenêtre est déjà ouverte en arrière plan il, si c'est le cas donc au lieu de créer une nouvelle, il va me ré-afficher la fenêtre existante?

    merci

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 612
    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 612
    Points : 25 303
    Points
    25 303
    Par défaut
    Il te suffit de conserver une référence vers la MDIChild dans un membre privé de la MDIForm, avec Assigned tu pourras vérifier si un Create est nécessaire ou pas

    Tu peux aussi utiliser la variable globale automatiquement crée mais on a souvent des sujets sur des doublons d'instances, donc soit prudent avec !

  3. #3
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    J'ai pas bien saisie votre reponse !

  4. #4
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    form2 étant la fiche Child
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      if not Assigned (form2) then
        Application.CreateForm(TForm2, Form2);

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 612
    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 612
    Points : 25 303
    Points
    25 303
    Par défaut
    , pourtant, je t'avais déjà donné les mêmes infos dans ton précédent sujet Aide sur mon Form

    Deux TForm
    TParentForm, de style fsMDIForm, déclaré dans l'unité FrmParent
    TChildForm, de style fsMDIChild, déclaré dans l'unité FrmChild

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    uses ... FrmChild;
     
    type
      TParentForm = class(TForm)
        BtnCallChild: TButton;
        procedure BtnCallChildClick(Sender: TObject);
      private
        FChild: TChildForm; // référence vers la MDIChild dans un membre privé de la MDIForm
      ...
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TParentForm.BtnCallChildClick(Sender: TObject);
    begin
      // Assigned tu pourras vérifier si un Create est nécessaire ou pas
      if not Assigned(FChild) then
        FChild := TChildForm.Create(Self);
     
      FChild.Show();
    end;

  6. #6
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    En plus complet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      if not Assigned (form2) then
        Application.CreateForm(TForm2, Form2)
      else
        ShowWindow(Form2.Handle, SW_RESTORE) ;

  7. #7
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    merci beaucoup à vous tous.

  8. #8
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    Bonjour
    Votre solution a bien marché, mais un autre soucis est apparu:

    Quand je ferme une Form MDICHILD et que je ressaye de l'ouvrir, une erreur s'affiche et me dit 'violation de l'adresse...', alors qu'avant, cette erreur n'existait pas!

    A noter que dans l'evenement du OnClose du form MDICHild j'ai cette ligne:

  9. #9
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    Dans ce cas mettre plutôt le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        try
          ShowWindow(Form2.Handle, SW_RESTORE)
        except
          Application.CreateForm(TForm2, Form2)
        end ;
    Si la réponse te convient finaliser la discussion

  10. #10
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    Non votre solution ne m'a pas aidé...

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 612
    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 612
    Points : 25 303
    Points
    25 303
    Par défaut
    Attention au caFree, si tu conserves une référence extérieure, c'est très dangereux !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    uses ... FrmChild;
     
    type
      TParentForm = class(TForm)
        BtnCallChild: TButton;
        procedure BtnCallChildClick(Sender: TObject);
      private
        FChild: TChildForm; // référence vers la MDIChild dans un membre privé de la MDIForm
        FChildOldDestroyEventHandler: TNotifyEvent;
        procedure ChildDestroyEventHandler(Sender: TObject);
      ...
      end;
    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
    procedure TParentForm.BtnCallChildClick(Sender: TObject);
    begin
      // Assigned tu pourras vérifier si un Create est nécessaire ou pas
      if not Assigned(FChild) then
      begin
        FChild := TChildForm.Create(Self);
        FChildOldDestroyEventHandler := FChild.OnDestroy;
        FChild.OnDestroy := ChildDestroyEventHandler;
      end;
     
      FChild.Show();
    end;
     
    procedure TParentForm.ChildDestroyEventHandler(Sender: TObject);
    begin
      if Sender = FChild then
        FChild := nil;
     
      if Assigned(FChildOldDestroyEventHandler) then
        FChildOldDestroyEventHandler(Sender);
    end;




    Tu peux aussi utiliser Components[] et FindComponent au lieu d'une référence externe,
    c'est une toute autre solution

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    uses ... FrmChild;
     
    type
      TParentForm = class(TForm)
        BtnCallChild: TButton;
        procedure BtnCallChildClick(Sender: TObject);
      private
        // pas de référence !
      ...
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure TParentForm.BtnCallChildClick(Sender: TObject);
    var
      ChildForm: TChildForm; // référence locale !
    begin
      ChildForm := Self.FindComponent('ChildFormCalledByParent');
     
      if not Assigned(ChildForm) then
      begin
        ChildForm := TChildForm.Create(Self);
        ChildForm.Name:= 'ChildFormCalledByParent';
      end;
     
      ChildForm.Show();
    end;

  12. #12
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    Avec votre solution, Es-ce que j’élimine le CaFree?

  13. #13
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 612
    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 612
    Points : 25 303
    Points
    25 303
    Par défaut
    La Solution ICI du 2012-03-12, 16h09 fonctionne SANS caFree, la libération de TParentForm libéra aussi TChildForm
    C'est l'utilisation Self dans BtnCallChildClick qui passe une instance de TParentForm comme Onwer de l'instance de TChildForm, le Owner est le responsable "mémoire" des objets, une sorte de "Libération Automatique \ Garbage Collector", si l'on ose faire cet amalgame

    Les Solutions ICI du 2012-03-13, 10h07 supporte un caFree qui n'est pas forcément utile !

  14. #14
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    Voici l'exemple de la solution que je t'ai proposé.
    Fichiers attachés Fichiers attachés

  15. #15
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    Merci beaucoup pour vos solutions que vous m'avez proposé.

    bon pour la solution qui est sans CaFree, elle fonctionne bien mais ne ferme pas les fenetres MDICHild, elle les reduit et les laisse comme sa meme quand je les reouvert.

    Pour l'autre solution, je l'ai essayé, mais ya plein d'erreurs de violation d'adresse.

  16. #16
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    Est ce que tu as testé l'exemple que je t'ai envoyé ?

  17. #17
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    Oh je ne l'ai pas vu, sorry, je vais le voir et vous repondre, merci...

  18. #18
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    Sur votre exemple, quand je clique sur le button, il me fait : "violation d’accès à l'adresse..." et c'est exactement identique à mon problème.

  19. #19
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 612
    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 612
    Points : 25 303
    Points
    25 303
    Par défaut
    Citation Envoyé par scholes Voir le message
    bon pour la solution qui est sans CaFree, elle fonctionne bien mais ne ferme pas les fenetres MDICHild, elle les reduit et les laisse comme sa meme quand je les reouvert.
    utilise caHide à la place de caFree, cela va cacher au lieu de réduire, tu pourras ainsi utilisé le code du 2012-03-12, 16h09


    Citation Envoyé par scholes Voir le message
    Pour l'autre solution, je l'ai essayé, mais ya plein d'erreurs de violation d'adresse.
    Justement, les codes fournis doivent gérer les problèmes de violation d'accès !
    Si tu en as, c'est que tu as mal appliqué l'une des deux méthodes adaptées pour supporter le caFree !
    Les deux méthodes ne fonctionnent pas ? très étrange !


    Citation Envoyé par scholes Voir le message
    Sur votre exemple, quand je clique sur le button, il me fait : "violation d’accès à l'adresse..." et c'est exactement identique à mon problème.
    C'est normal, le code de construction de Exemple.zip est en commentaire, il faut le remettre
    le problème c'est que couplé qu'au caFree, Form2 prend une valeur invalide !

    code de Exemple.zip corrigé en utilisant la variable globale Form2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if not Assigned (Form2) then
        Form2 := TForm2.CreateForm(Self);
     
      Form2.Show();
    end;
    soit ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := caFree;
      Form2 := nil;
    end;
    soit ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := caHide;
    end;

  20. #20
    Nouveau membre du Club
    Inscrit en
    Avril 2008
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 173
    Points : 39
    Points
    39
    Par défaut
    Voilà, quand on fait : Form2:=nil sa marche bien.

    et Concernant le CaHide, d'apres mes connaissance le MDICHILD ne peut pas etre mit en Hide, je vais tester pour confirmer les deux cas.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. interchanger des fsMDIChild depuis une form fsMDIForm
    Par rogerpierre dans le forum Débuter
    Réponses: 5
    Dernier message: 08/06/2012, 19h46
  2. Transparence d'une forme dans une MDIChild
    Par Sub13 dans le forum Delphi
    Réponses: 2
    Dernier message: 14/12/2006, 09h50
  3. Form MDI et MDIChild
    Par philippef dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 23/08/2006, 18h52
  4. Form de type MDICHILD dans uen DLL =>KO
    Par QAYS dans le forum Delphi
    Réponses: 1
    Dernier message: 01/07/2006, 10h51
  5. Réponses: 2
    Dernier message: 16/10/2005, 14h07

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