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 :

Frame.Free à partir d'une Form?


Sujet :

Langage Delphi

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

    Informations forums :
    Inscription : Août 2004
    Messages : 123
    Points : 68
    Points
    68
    Par défaut Frame.Free à partir d'une Form?
    Bonjour

    Dans une form, j'aimerais créer un frame dynamiquement. Lorsque l'utilisateur clique sur un bouton du frame, la form doit décharger la frame de la mémoire en appelant sa méthode Free().

    J'ai lu que la méthode correcte est d'utiliser un objet TNotifyEvent pour que le frame puisse envoyer un signal à la form, et dans la form, utiliser la méthode PostMessage() pour que la form puisse décharger la frame proprement via la boucle de messages.

    J'ai deux questions:
    1. Est-ce effectivement la bonne méthode, et n'y en a-t-il pas de plus simple?
    2. J'ai une erreur à la compilation à la ligne où j'appelle PostMessage

    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
    //=========== Frame
    type
      TFrame3 = class(TFrame)
      private
        FOnDone: TNotifyEvent;
      public
        property OnDone: TNotifyEvent read FOnDone write FOnDone;
      end;
    
    procedure TFrame3.Button2Click(Sender: TObject);
    begin
      if Assigned(FOnDone) then begin
        FOnDone(Self);
      end;
    end;
    
    //=========== Form
    const
      APPWM_FREE_FRAME = WM_APP + 100;
    
    type
      TForm1 = class(TForm)
      private
        procedure FrameIsDone(Sender: TObject);
        procedure AppWmFreeFrame(var Message: TMessage); message
    APPWM_FREE_FRAME;
      end;
    
    implementation
    
    var
      Frame3 : TFrame3;
    
    procedure TForm1.AppWmFreeFrame(var Message: TMessage);
    begin
        TFrame(Message.LParam).Free;
    end;
    
    procedure TForm1.FrameIsDone(Sender: TObject);
    begin
      if Sender is TFrame3 then begin
    
    //E2010 Incompatible types: 'Integer' and 'TFrame3'
    PostMessage(Handle, APPWM_FREE_FRAME, 0, Frame3);
    
      end;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Frame3 : TFrame3;
    begin
      Frame3 := TFrame3.Create(nil);
      Frame3.Align := alClient;
      Frame3.Parent := Self;
      Frame3.OnDone := FrameIsDone;
      Frame3.Visible := True;
    end;
    Merci pour toute piste.

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 123
    Points : 68
    Points
    68
    Par défaut
    L'erreur disparait si je cast ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PostMessage(Handle, APPWM_FREE_FRAME, 0, Integer(Frame3));
    Qu'en pensez-vous?

  3. #3
    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
    Tu reproduis la fonction Release d'une TForm, c'est une idée, ... je l'avais fait avec une autre solution, j'avais un FrameManager (une Liste en fait de Form car je n'utilisais pas de Frame en Delphi 3), j'indiquais que l'instance en cours devait être nettoyé, et lors du OnIdle de l'application, je procédais à la libération, mais ton enchainement de message est pas mal ...

    tu peux essayer ceci pour moi ? je crois que c'est fonctionnel et plus simple ! cela fait juste la libération sans avoir de Event de la forme qui peut transformer des transtypages en Usine à Gaz !!!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure TFrame3.CMRelease(var Message: TMessage); // message CM_RELEASE;
    begin
      Free;
    end;
     
    procedure TFrame3.Release;
    begin
      PostMessage(Handle, CM_RELEASE, 0, 0);
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TFrame3.Button2Click(Sender: TObject);
    begin
      Release();
    end;
    Sinon mets l'appel de FOnDone dans une méthode DoDone, c'est souvent comme ça que l'on fait

  4. #4
    Membre éclairé Avatar de Kaféine
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 569
    Points : 736
    Points
    736
    Par défaut
    Salut,

    je ne comprend pas la problématique.
    Lors du clique dans un bouton de la frame il suffit d'appeler la méthode Free de la frame en question non?

    pourquoi est ce que ca devrais être la form containeur qui appelerais le free de la frame?

  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
    Je ne sais pas non plus, une histoire de gestionnaire d'évènement qui libère son composant en cours, avec une forme, c'est problématique, ... avec une Frame peut-être aussi, je ne sais pas, je n'en utilise pas !
    C'est pour cela que je suis parti dans la comparaison avec un Release ... d'ailleurs en général libérer un objet durant un gestionnaire d'évènement, c'est un risque puisque l'on ne sait pas ce qui se passe après l'appel de l'évènement et donc il peut faire une violation d'accès ...

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 123
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    tu peux essayer ceci pour moi ? je crois que c'est fonctionnel et plus simple ! cela fait juste la libération sans avoir de Event de la forme qui peut transformer des transtypages en Usine à Gaz !!!
    Justement, on m'a dit qu'il n'était pas fiable que la frame appelle elle-même la fonction Free, et qu'il fallait laisser ça à la form parent, d'où l'utilisation d'un objet TNotifyEvent afin de faire communiquer la frame et la form sans personnaliser la frame (avant ça, j'appelais directement de la frame une procedure du genre TForm1.GetMessage).

    J'ai besoin non seulement que la frame soit déchargée de la mémoire via Free() mais aussi que la form parent soit prévenue de l'évènement afin par exemple de réactiver un menu.

    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon mets l'appel de FOnDone dans une méthode DoDone, c'est souvent comme ça que l'on fait
    Je ne suis pas sûr de comprendre : tu veux dire qu'on peut définir une propriété pour qu'elle appelle directement une procédure, du genre:

    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
     
    type
      TFrame3 = class(TFrame)
      private
        FOnDone: TNotifyEvent;
      public
        property OnDone: TNotifyEvent read DoDone() write DoDone()
      end;
     
    procedure TFrame3.DoDone(Sender: TObject);
    begin
      if Assigned(FOnDone) then begin
        FOnDone(Self);
      end;
    end;
    La ligne property va continuer à fonctionner, et notamment permettre à la form parent de lier cette propriété avec une procédure dans la form qui est appelée par la frame?

    Citation Envoyé par ShaiLeTroll Voir le message
    en général libérer un objet durant un gestionnaire d'évènement, c'est un risque puisque l'on ne sait pas ce qui se passe après l'appel de l'évènement et donc il peut faire une violation d'accès ...
    Oui, c'est exactement ce qu'on m'a expliqué, d'où le conseil de laisser la form parent se charger d'appeler FrameX.Free().

  7. #7
    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
    Sinon, le code du Release que j'ai fourni peut être amélioré

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TFrame3.Release;
    begin
      DoDone(); // Juste pour la notification pas faire le Free dedans ...
      PostMessage(Handle, CM_RELEASE, 0, 0);
    end;
     
    procedure TFrame3.CMRelease(var Message: TMessage); // message CM_RELEASE;
    begin
      Free;
    end;
    l'important ce n'est pas quel objet qui contient la méthode de libération, mais QUAND c'est fait ! et l'astuce est uniquement dans le PostMessage ...


    Tu regarde un peu les unités fournies avec Delphi, pour le Do je ne parlais pas d'un accesseur (sinon j'aurais dit Get et Set) mais d'un "Appeleur" (il y a un terme mais je ne le connais pas)

    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
    type
      TFrame3 = class(TFrame)
      private
        FOnDone: TNotifyEvent;
      protected
        procedure DoDone(); virtual; // Très pratique pour intercepter l'évènement dans un héritier
      public
        property OnDone: TNotifyEvent read FOnDone write FOnDone;
      end;
     
    procedure TFrame3.DoDone();
    begin
      if Assigned(FOnDone) then 
        FOnDone(Self);
    end;

Discussions similaires

  1. fermer une frame a partir d'une autre frame
    Par zekmek dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 09/10/2006, 13h31
  2. Récupérer adresse url d'une frame a partir d'une autre
    Par ok07 dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 08/08/2006, 23h53
  3. Comment ouvrir Outlook Express à partir d'une form ( Form's buider d'oracle)?
    Par Fleur-Anne.Blain dans le forum Outlook Express / Windows Mail
    Réponses: 3
    Dernier message: 17/07/2006, 11h15
  4. Créer un rtf à partir d'une form
    Par akabane dans le forum Delphi
    Réponses: 2
    Dernier message: 07/06/2006, 10h18
  5. [rechargement d'une frame mère à partir d'une frame fille]
    Par Lady_jade dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 09/12/2005, 11h02

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