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 :

Problème avec la libération d'une Form créée dynamiquement


Sujet :

Langage Delphi

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Août 2004
    Messages
    696
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 696
    Points : 225
    Points
    225
    Par défaut Problème avec la libération d'une Form créée dynamiquement
    Bonjour,
    J'ai un problème avec une forme que je créer dynamiquement.

    je m'explique.

    je créer une form :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Form2 := Tform2.Create()
    a la destruction

    j'ai toujours dans l'inspecteur d'objet des information spour form2 en résumé il n'est plus a nil

    pouvez-vous m'aider

    merc

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 456
    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 456
    Points : 24 868
    Points
    24 868
    Par défaut
    Tu as ton Singleton Form2 ... est-ce la seule variable qui contiendra une Tform2 (en gros, cette fenêtre n'est lancé qu'une fois à la fois ?), si oui, tu peux dans le Destructeur (override Destroy) ajouter une affectation à nil de ton singleton Form2 (tu as plein d'exemple sur le forum ICI ou LA)
    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

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Août 2004
    Messages
    696
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 696
    Points : 225
    Points
    225
    Par défaut
    Bonjour,

    merci de votre réponse, en fait je veux appeler cette forme plusieurs fois:

    un peu comme outlook, soit
    FormA := Tform2.Create;
    FormB := Tform2.create;


    Je peux fermer FormA la c'est ok par contre j'aurais des problème avec la formB (je fait surment quelque chose de pas bien)

    D'ailleurs lorsque je creer la formA si je fait un showmald j'ai un message d'erreur

    PS: il s'agit de mon premier programme (création d'objet écran)

    Merci

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 560
    Points : 576
    Points
    576
    Par défaut
    Bonjour,

    Vous pouvez essayer quelque chose de ce genre.

    1° Ajouter Dans votre forme un évènement A faire lors du OnClosequery de la forme.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      property EventWhereCloseQuery: TNotifyEvent read FEventWhereCloseQuery write FEventWhereCloseQuery;
    Lors de la création de la form assigner cette procédure a une valeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     FormA := TMyform.create(Self);
      FormA.EventWhereCloseQuery := MyProcedureClose;
    Dans le OnClosequery de votre forme (TMyform) Tester si EventWhereCloseQuery Existe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      if assigned(EventWhereCloseQuery) then begin
        EventWhereCloseQuery(Self); // Lance la procedure
       CanClose := nil; // Anule la destruction
      end;
    Maintenant implémenter la procédure que vous aller lancer durant le OnClose.
    [CODE]
    Procedure MyProcedureClose(Sender: TObject);
    begin
    If not (Sender is TMyform) then exit;
    FormToClose := Sender As TMyforme;
    FormToClose.EventWhereCloseQuery := nil;
    TimerClose.Enabled := true; // Le timer peut être tres court, 10 ou 20 par exemple
    End;

    Dans le OnTimer de TimerClose vous pouvez Fermer/ Détruire la forme et fait tout les nettoyage que vous désirer.

    Explication théorique:

    Lorsque je fais le OnClose sur Le TMyform Je detecte la procedure EventWhereCloseQuery.
    Je lance donc la procedure et j'annule la destruction.

    La procédure Stoke la forme de type TMyform qui est a l'origine de l'apelle.
    Elle mes sont évènement EventWhereCloseQuery à nil (ce qui évitera de boucler dans le Onclosequery de la forme) Et lance un timer.

    Lorsque le time ce déclenche je suis en dehors de tout évènement de la forme a détruire. Et surtout en dehors des évènement qui interfèreront avec mes ordres de destruction (Un OnCloseQuery qui lance Un Destroy ou un free ne fonctionne pas correctement).
    2tant à l'extérieure de la forme, je peut Chercher la référence de ma forme et nettoyer derrière mois.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      if  FormToClose = formA then begin
        ForAa.Destroy;
        FormA := nil;
      end;
    Je sais, c'est lourd. J'en suis désolé, mais je n'ai pas mieux.

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Août 2004
    Messages
    696
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 696
    Points : 225
    Points
    225
    Par défaut
    JE vous remerci de votre aide, à charge de revanche

    Cordialement
    QAYS

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 456
    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 456
    Points : 24 868
    Points
    24 868
    Par défaut
    il existe une autre méthode, il suffit d'ajouter dans une TList un Pointeur sur l'Objet (oui oui un pointeur sur le pointeur de référence pour le mettre à nil), tient ça devrait donner cela ...

    il faut que FormA et FormB soient des variables globales ou à la limite une propriété d'un objet sans accesseur méthode ... en théorie cela fonctionne (en fait en pratique je viens faire le test, donc je fourni le code propre)

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    unit Frm_SingletonManager;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      PSingletonObject = ^TObject;
     
      TFrmSingletonManager = class(TForm)
        ButtonClose: TButton;
        procedure ButtonCloseClick(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Déclarations privées }
      public
        destructor Destroy; override;
        class procedure AddSingleton(ASingleton: PSingletonObject);
        { Déclarations publiques }
      end;
     
    var
      FrmSingletonManager: TFrmSingletonManager;
     
    implementation
     
    {$R *.dfm}
     
    var
      _FrmSingletonManager: TList = nil;
     
    class procedure TFrmSingletonManager.AddSingleton(ASingleton: PSingletonObject);
    begin
      if not Assigned(_FrmSingletonManager) then
        _FrmSingletonManager := TList.Create(); 
     
      _FrmSingletonManager.Add(ASingleton);
    end;
     
    destructor TFrmSingletonManager.Destroy(); // override;
    var
      i: Integer;
    begin
      if Assigned(_FrmSingletonManager) then
      begin
        for i := 0 to _FrmSingletonManager.count - 1 do
        begin
          if PSingletonObject(_FrmSingletonManager.Items[i])^ = Self then
          begin
            // Items[i] pointe sur l'emplacement mémoire du pointeur de la variable contenant elle même le pointeur sur la référence ...
            PSingletonObject(_FrmSingletonManager.Items[i])^ := nil;
            _FrmSingletonManager.Delete(i);
            break;
          end;			
        end;
      end;
     
      inherited Destroy();
    end;
     
    procedure TFrmSingletonManager.ButtonCloseClick(Sender: TObject);
    begin
      Close();
    end;
     
    procedure TFrmSingletonManager.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      Action := caFree;
    end;
     
    initialization
      _FrmSingletonManager := TList.Create();
     
    finalization
      if Assigned(_FrmSingletonManager) then
      begin
        _FrmSingletonManager.Free();
        _FrmSingletonManager := nil;
      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
    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
    var
      SingletonA, SingletonB, SingletonC: TFrmSingletonManager;
     
    procedure TFrmTestDivers.BtnSingletonManagerAClick(Sender: TObject);
    begin
      SingletonA := TFrmSingletonManager.Create(Self);
      TFrmSingletonManager.AddSingleton(@SingletonA);
      SingletonA.Show();
    end;
     
    procedure TFrmTestDivers.BtnSingletonManagerBClick(Sender: TObject);
    begin
      SingletonB := TFrmSingletonManager.Create(Self);
      TFrmSingletonManager.AddSingleton(@SingletonB);
      SingletonB.Show();
    end;
     
    procedure TFrmTestDivers.BtnSingletonManagerCClick(Sender: TObject);
    begin
      SingletonC := TFrmSingletonManager.Create(Self);
      TFrmSingletonManager.AddSingleton(@SingletonC);
      SingletonC.Show();
    end;
     
    procedure TFrmTestDivers.BtnSingletonManagerAIsNilClick(Sender: TObject);
    begin
      ShowMessage(BoolToStr(not Assigned(SingletonA), True));
    end;
     
    procedure TFrmTestDivers.BtnSingletonManagerBIsNilClick(Sender: TObject);
    begin
      ShowMessage(BoolToStr(not Assigned(SingletonB), True));
    end;
     
    procedure TFrmTestDivers.BtnSingletonManagerCIsNilClick(Sender: TObject);
    begin
      ShowMessage(BoolToStr(not Assigned(SingletonC), True));
    end;
    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

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

Discussions similaires

  1. OpenGl rendering dans une form créée dynamiquement
    Par hey_monkey dans le forum Débuter
    Réponses: 5
    Dernier message: 14/12/2011, 11h07
  2. Remplir une forme crée avec un polygon
    Par declencher dans le forum Débuter
    Réponses: 2
    Dernier message: 03/01/2009, 16h17
  3. Problème avec un tween sur des clips crées dynamiquement
    Par Invité dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 21/05/2008, 17h43
  4. [Excel] Charger une form créée dynamiquement dans un autre classeur
    Par spileo dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 28/02/2007, 11h58
  5. Problèmes avec une TForm créée dynamiquement
    Par Pascal Jankowski dans le forum Composants VCL
    Réponses: 5
    Dernier message: 30/03/2005, 11h55

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