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 :

Libération de formes ouvertes en cascade


Sujet :

Langage Delphi

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Responsable societe packaging
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable societe packaging

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut Libération de formes ouvertes en cascade
    Bonsoir a tous,
    J'ai un problème de libération de form.
    Ex :
    Form principale lance une forme devis qui lance une form tiers, qui peut lancer une autre form devis.
    Lorsque je libère la deuxième form devis, pas de problèmes, après nous sortons de la fiche tiers et la liberons avec un formdevis.release, pas de problèmes et nous sommes revenus a la première form devis.
    Lorsque nous fermons cette fiche j'ai un message d'erreur.
    La première instruction release de la form devis fait planter la deuxième lors de sa liberation.
    Comment faire?
    Merci pour votre aide.
    Max

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Points : 5 918
    Points
    5 918
    Par défaut
    Bonjour,
    Citation Envoyé par maxjp83 Voir le message
    Lorsque nous fermons cette fiche j'ai un message d'erreur.
    Quel message d'erreur ? Violation d'accès ou autre ?

    Citation Envoyé par maxjp83 Voir le message
    Form principale lance une forme devis qui lance une form tiers, qui peut lancer une autre form devis.
    Comment est-elle créée ? Application.CreateForm(TMaForm, MaForm); ou MaForm := TMaForm.Create(Self); ou MaForm := TMaForm.Create(nil); ?
    Comment est-elle affichée ? ShowModal ?

    Citation Envoyé par maxjp83 Voir le message
    Lorsque je libère la deuxième form devis, pas de problèmes, après nous sortons de la fiche tiers et la liberons avec un formdevis.release, pas de problèmes et nous sommes revenus a la première form devis.
    Lorsque nous fermons cette fiche j'ai un message d'erreur.
    La première instruction release de la form devis fait planter la deuxième lors de sa liberation.
    Le code serait le bienvenu. AMHA, il reste un élément référencé pour lequel plus d'une libération mémoire est tentée...

  3. #3
    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 : 55
    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 457
    Points
    28 457
    Par défaut
    je mise sur l'usage de la variable globale formdevis: Tformdevis

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Responsable societe packaging
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable societe packaging

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Ph. B. Voir le message
    Bonjour,

    Quel message d'erreur ? Violation d'accès ou autre ?


    Comment est-elle créée ? Application.CreateForm(TMaForm, MaForm); ou MaForm := TMaForm.Create(Self); ou MaForm := TMaForm.Create(nil); ?
    Comment est-elle affichée ? ShowModal ?


    Le code serait le bienvenu. AMHA, il reste un élément référencé pour lequel plus d'une libération mémoire est tentée...
    Bonjour Philippe,

    Je crée toutes mes formes avec Application.CreateForm(TMaForm, MaForm)
    Toutes les fiches sont indépendantes, mais il y a dans mon exemple deux memes formes qui sont appellées avec des param différents (par exemple pour visualiser un ancien devis).
    Lorsque je libère la deuxième forme crée ex Application.CreateForm(TFormDevis, MaFormDevis) puis showmodal et MaFormDevis.release, cela impact la première formdevis.

    Le message est Violation d'accès a l'adresse 6C3B6300, lecture de l'adresse 6C3B6300.
    Pourtant il y a deux createForm différents a deux moment différents. Avant la libération de la première formDevis crée, elle fonctionne normalement, c'est seulement au moment de la fermeture.
    On dirait qu'il associe les noms des deux formes à la même adresse.

    Merci pour ton aide!!

    Max

  5. #5
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 885
    Points : 11 403
    Points
    11 403
    Billets dans le blog
    6
    Par défaut
    Y a-t-il bien Application.CreateForm(TFormDevis, MaFormDevis_1) et Application.CreateForm(TFormDevis, MaFormDevis_2), ou Paul Toth aurait-il une boule de cristal détectant les CANPF ?

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Responsable societe packaging
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable societe packaging

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    je mise sur l'usage de la variable globale formdevis: Tformdevis

    Merci pour ta réponse.
    Les formes sont appelées a des moments différents et traitent des données différentes. Ce problème est commun a toutes mes fiches chargées plusieurs fois, et j'ai au moins une centaine de formes...
    Max

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Responsable societe packaging
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable societe packaging

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Y a-t-il bien Application.CreateForm(TFormDevis, MaFormDevis_1) et Application.CreateForm(TFormDevis, MaFormDevis_2), ou Paul Toth aurait-il une boule de cristal détectant les CANPF ?

    Sur le principe c'est ce qu'il faudrait, mais dans Application.CreateForm(TFormDevis, MaFormDevis_1) MaFormDevis_1, n'existe pas et Delphi ne l'accepte pas, il faudrait qq chose comme dans une requete select nom as nom1.

    Comment faire?

    Merci

    Max

  8. #8
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 885
    Points : 11 403
    Points
    11 403
    Billets dans le blog
    6
    Par défaut
    Si tu utilises le même nom de variable pour référencer successivement des instances différentes, d'une part on perd toutes les premières références pour ne conserver que la dernière, d'autre part, en libérant une instance déjà libérée, on a une violation d'accès.

    La solution est donc d'avoir plusieurs noms de variables du même type (ici, un par fiche) ou une liste de fiches (TList, TObjectList), voire une pile (TStack) si on doit les libérer en sens inverse de leur création (LIFO), ou un code sans référence explicitement conservée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    with TMaFiche.Create(nil) do 
    begin
      try
          // initialisations
        MaPropriete:=2;
        Init(MonParametre);
          // affichage
        ShowModal;  
      finally
          // libération
        Free;
    end;

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Responsable societe packaging
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable societe packaging

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Si tu utilises le même nom de variable pour référencer successivement des instances différentes, d'une part on perd toutes les premières références pour ne conserver que la dernière, d'autre part, en libérant une instance déjà libérée, on a une violation d'accès.

    La solution est donc d'avoir plusieurs noms de variables du même type (ici, un par fiche) ou une liste de fiches (TList, TObjectList), voire une pile (TStack) si on doit les libérer en sens inverse de leur création (LIFO), ou un code sans référence explicitement conservée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    with TMaFiche.Create(nil) do 
    begin
      try
          // initialisations
        MaPropriete:=2;
        Init(MonParametre);
          // affichage
        ShowModal;  
      finally
          // libération
        Free;
    end;

    Merci pour ta réponse, j'essaierais, et je te tiens au courant!
    Bon we

    Max

    Merci encore, tout fonctionne parfaitement.

    Max

  10. #10
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Points : 5 918
    Points
    5 918
    Par défaut
    Bonjour,
    Citation Envoyé par maxjp83 Voir le message
    Je crée toutes mes formes avec Application.CreateForm(TMaForm, MaForm)
    Mais en gardant la même variable MaForm...

    Lors du 1° appel, la variable MaForm est initialisée (disons qu'elle reçoit la valeur d'adresse 1000 correspondant à la 1° fiche)
    Lors du deuxième appel, la variable MaForm est réinitialisée (disons qu'elle reçoit la valeur d'adresse 2000 correspondant à la 2° fiche)
    On ferme la 2° fiche et on libère les ressources (MaForm.release) pour MaForm = 2000. Tout va bien.
    On veut fermer la 1° fiche et libérer les ressources (MaForm.release), mais MaForm (=2000) fait référence à la 2° fiche. Cela déclenche alors une violation d'accès (les ressources sont déjà libérées et n'appartiennent plus à l'application)

    Comme ce sont des fiches modales, 3 solutions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TMaParentForm.AppelMaForm;
    var
      LocalMaForm: TMaForm;
    begin
      Application.CreateForm(TMaForm, LocalMaForm);
      try
        LocalMaForm.ShowModal;
      finally
        LocalMaForm.Release;
      end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure TMaParentForm.AppelMaForm;
    var
      LocalMaForm: TMaForm;
    begin
      LocalMaForm := TMaForm.Create(Self);  
      // ou car on va gérer la libération directement, on indique pas un propriétaire (Owner)
      // LocalMaForm := TMaForm.Create(nil);
      try
        LocalMaForm.ShowModal;
      finally
        LocalMaForm.Release;
      end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TMaParentForm.AppelMaForm;
    begin
      // Pas besoin de variable ni de propriétaire (Owner)
      // On gère directement la libération
      with TMaForm.Create(nil) do
      try
        ShowModal;
      finally
        Release;
      end;
    end;
    La dernière a ma préférence bien entendu...

  11. #11
    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 : 55
    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 457
    Points
    28 457
    Par défaut
    à noter que bien souvent quand on est en instances multiples, l'usage d'une variable globale devient lourd.

    donc, soit l'instance n'a pas besoin de la variable, notamment si la fiche vie sa vie et qu'on n'a jamais besoin d'y faire référence, dès lors on se fiche de la variable.

    soit on place dans une liste (TList, TObjectList, array of ... au choix) toutes les instances créées.

    on peux par exemple avoir une TList dans la fiche principale (MainForm qui elle est unique à l'application) et le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      MainForm.List.Add(Self);
    end;
     
    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      MainForm.List.Remove(Self);
    end;

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Responsable societe packaging
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable societe packaging

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    à noter que bien souvent quand on est en instances multiples, l'usage d'une variable globale devient lourd.

    donc, soit l'instance n'a pas besoin de la variable, notamment si la fiche vie sa vie et qu'on n'a jamais besoin d'y faire référence, dès lors on se fiche de la variable.

    soit on place dans une liste (TList, TObjectList, array of ... au choix) toutes les instances créées.

    on peux par exemple avoir une TList dans la fiche principale (MainForm qui elle est unique à l'application) et le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      MainForm.List.Add(Self);
    end;
     
    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      MainForm.List.Remove(Self);
    end;
    Bonjour Paul,

    Merci beaucoup pour ton aide, tout fonctionne parfaitement!!!

    Max

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Responsable societe packaging
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable societe packaging

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Merci pour votre aide à tous!!!!

    Max

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

Discussions similaires

  1. [Forms 6i] Trouver tous les form ouverts
    Par reppier dans le forum Forms
    Réponses: 2
    Dernier message: 12/10/2007, 20h19
  2. détecter click hors form ouverte modale
    Par jlf dans le forum Delphi
    Réponses: 7
    Dernier message: 26/03/2007, 18h00
  3. [Form et popup] target d'un form ouvert dans une popup
    Par Flobel dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 19/01/2007, 22h05
  4. Libération de form, Free vs Release
    Par Lung dans le forum Delphi
    Réponses: 36
    Dernier message: 02/12/2006, 14h36
  5. [WinForms]Connaitre le plan des forms ouvertes
    Par NiamorH dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 09/09/2006, 13h03

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