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

C++Builder Discussion :

TForm et parents


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 86
    Points : 81
    Points
    81
    Par défaut TForm et parents
    Bonjour,

    J'ai des difficultés à comprendre le fonctionnement des relations parents/enfants entre TForm.

    J'ai une application qui dois fonctionner sur deux écrans. Une fenêtre par écran.
    J'utilise donc deux "Application->CreateForm(...)"

    Sur la fenêtre de mon écran secondaire je veux ajouter un TForm qui dois prendre l'intégralité de la surface de la fenêtre. Ce TForm dois donc avoir comme parent la fenêtre.
    Ce que je ne comprend pas c'est où définir le parent de mon TForm ?
    Dans le constructeur de TForm ? (TForm* maForm = new TForm( formParent ); ou TForm* maForm = new TForm( formParent->Handle );
    Ou dans l'une des variables du TForm ? maForm->Parent = formParent;

    Merci

  2. #2
    Membre chevronné
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Points : 2 189
    Points
    2 189
    Par défaut
    salut, je ne comprends pas pourquoi ta deuxième Form dois avoir la première comme Parent? Tu ne te trompe avec Owner. Normallement tu veux qu'une Form secondaire ait comme Owner la première. Comme ça, à la fermeture dans Form principale la deuxième sera aussi fermé.

    Reagade un peu la doc sur la création de fenêtre: http://docwiki.embarcadero.com/Libra...s.TForm.Create
    • Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
    • Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
    • Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 86
    Points : 81
    Points
    81
    Par défaut
    Quelle est la différence entre un owner et un parent.
    Je ne connaissais que les parent avec l'api win32 et QT.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par greg2 Voir le message
    Quelle est la différence entre un owner et un parent.
    Tu vas rigoler

    Owner c'est le propriétaire, c'est à dire l'objet qui est responsable de la desallocation de ta form [en gros dans le destructeur du propriétaire, le propriétaire va détruire tous "ces enfants"]
    Si tu veux une gestion manuelle de ta form, tu passes NULL au constructeur.


    Parent c'est le parent, c'est à dire l'objet qui va contenir et afficher ta form.
    Par exemple: Tu crées un bouton. Mais tant que tu n'as pas affecté son parent, il ne sera pas visible.

    Là où c'est rigolo, c'est que lorsque tu affectes le parent, le propriétaire est automatiquement le parent.
    Voire mon post en dessous: le parent peut détruire "ces enfants"

    Donc le propriétaire ne sert à rien:


    Tu es sûr que tu peux avoir 2 forms principales? Il y a une limitation: 1 et 1 seule form principale

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 86
    Points : 81
    Points
    81
    Par défaut
    En fait je fais une migration d'un programme sous 2010 vers XE8 et j’essaie de comprendre pourquoi une de mes fenêtre "enfant" ne s'affiche pas.

    Tu es sûr que tu peux avoir 2 forms principales? Il y a une limitation: 1 et 1 seule form principale
    Est ce que ça veux dire si je crée deux fenêtres dans le WinMain comme ci-dessous, c'est sensé être mauvais ?

    Application->CreateForm(__classid(TV_ihm), &V_ihm);
    Application->CreateForm(__classid(TV_ihmMainDraw), &V_ihmMainDraw);

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Dans la documentation, c'est écrit "Note: By default, the form created by the first call to CreateForm in a project becomes the application's main form."

    Donc oui, c'est mauvais: tu ne sais pas vraiment ce qui va se passer: si la deuxième form sera créée en mémoire mais pas afficher et provoquer une fuite mémoire [à la fin] soit (en regardant l'exemple Embarcadero) la première form sera détruite et remplacée par le deuxième.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 86
    Points : 81
    Points
    81
    Par défaut
    Avec cet exemple, ça semble fonctionner (cf fichier joint). Et sur l'application que je porte aussi (avec 2010 depuis longtemps, mais mal avec XE8).
    Peut-être qu'une des deux fenêtre est considérer comme une fenêtre "principale" mais qu'on peut quand même en ajouter (même si elle ne sont pas considérés comme "principale")
    Est ce que ça fonctionne par chance ? Qu'est ce qu'il faudrait changer ?
    Fichiers attachés Fichiers attachés

  8. #8
    Membre chevronné
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Points : 2 189
    Points
    2 189
    Par défaut
    Citation Envoyé par greg2 Voir le message
    Peut-être qu'une des deux fenêtre est considérer comme une fenêtre "principale" mais qu'on peut quand même en ajouter (même si elle ne sont pas considérés comme "principale")
    Va dans Project / Options / Forms. Tu vas voir que la Main form est V_ihm.

    Citation Envoyé par greg2 Voir le message
    Qu'est ce qu'il faudrait changer ?
    Habituellement je préfère ne pas trop mettre de code dans le fichier où il y a le _tWinMain. Sa a la mauvaise habitude de corrompre le projet.
    Par exemple, je crois que ce code serais mieux dans le constructeur de leur Form respective:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
             V_ihm->Color         = clGray;
             V_ihmMainDraw->Color = clYellow;
    Aussi je ne comprends pas pourquoi tu va créer une fenêtre dans une fenêtre, mais bon...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
             DisplayInterface = new TForm(  (Classes::TComponent*)NULL  );
             if (DisplayInterface == NULL)
                return false;
     
             DisplayInterface->Parent       = V_ihmMainDraw;
             DisplayInterface->Color        = clGreen;
             DisplayInterface->BorderStyle  = bsNone;
             DisplayInterface->Align        = alClient;
             DisplayInterface->Show();
    1. Vu que DisplayInterface n'a pas de Owner, il ne sera jamais détruis. Il manque le delete.
    2. Habituellement en C++ tu ne met pas de vérification pour vérifier si le new à fonctionner. Si tu crois qu'il peut échouer il faut mettre un try / catch


    À la place de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            V_ihmMainDraw->Top = Screen->Monitors[1]->Top;
            V_ihmMainDraw->Left = Screen->Monitors[1]->Left;
            V_ihmMainDraw->Width = Screen->Monitors[1]->Width;
            V_ihmMainDraw->Height = Screen->Monitors[1]->Height;
    J'utiliserais ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            if(Screen->MonitorCount > 1)
            {
                V_ihmMainDraw->BoundsRect = Screen->Monitors[1]->BoundsRect;
            }
    • Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
    • Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
    • Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Crayon Voir le message
    Habituellement en C++ tu ne met pas de vérification pour vérifier si le new à fonctionner. Si tu crois qu'il peut échouer il faut mettre un try / catch
    Comment tu y vas

    Juste un test à NULL du nouveau pointeur.

    D'ailleurs il faut être sûr que le new lance une exception. Et si je ne dis pas de bêtises, il ne faut jamais qu'un constructeur ni même un destructeur lance une exception

    Un début d'explication:
    The reason that it is unwise to throw an exception in a constructor in C++ is that if construction of the object failes (an exception did occur), the deconstructor is never called. If something was 'newed-up' in the constructor, that object will still be around and can't be destroyed in any way (as there is no pointer) and now you have a memory leak.

  10. #10
    Membre chevronné
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Points : 2 189
    Points
    2 189
    Par défaut
    Salut foetus

    Citation Envoyé par foetus Voir le message
    Là où c'est rigolo, c'est que lorsque tu affectes le parent, le propriétaire est automatiquement le parent.

    Donc le propriétaire ne sert à rien:
    C'est faux, si on change le Parent cela n’affecte pas le Owner.
    Dans le code soumis par greg2, met un break point après la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
             DisplayInterface->Parent       = V_ihmMainDraw;
    et met dans ta Watch List: DisplayInterface->Owner
    Tu vas voir qu'il reste à NULL.

    Citation Envoyé par foetus Voir le message
    D'ailleurs il faut être sûr que le new lance une exception. Et si je ne dis pas de bêtises, il ne faut jamais qu'un constructeur ni même un destructeur lance une exception
    C'est OK de mettre une exception dans un constructeur. D'ailleurs il y a plein de classe où c'est le cas dans la VCL / RTL. Par contre, pour le destructeur tu as 100% raison.

    Va lire ceci: https://isocpp.org/wiki/faq/exceptions#ctors-can-throw
    • Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
    • Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
    • Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon

  11. #11
    Membre chevronné
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Points : 2 189
    Points
    2 189
    Par défaut
    Citation Envoyé par foetus Voir le message
    Juste un test à NULL du nouveau pointeur.
    Je viens de retrouver ce que je cherchais: Do I need to check for null after p = new Fred()?
    • Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
    • Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
    • Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Crayon Voir le message
    C'est faux, si on change le Parent cela n’affecte pas le Owner.
    Cela semble dépendre de la descendance

    Note: The Parent property declared in TControl is similar to the Owner property declared in TComponent, in that the Parent of a control frees the control just as the Owner of a component frees that Component.

    documentation TControl.Parent

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 86
    Points : 81
    Points
    81
    Par défaut
    C'était juste un code de démonstration. Le changement de couleur c'était pour bien voir les différentes fenêtres.
    J'ai besoin de mettre une form dans la la fenêtre pour pouvoir y accrocher un rendu OpenGL

  14. #14
    Membre chevronné
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Points : 2 189
    Points
    2 189
    Par défaut
    Citation Envoyé par foetus Voir le message
    Cela semble dépendre de la descendance



    documentation TControl.Parent
    Donc, d'après ce que je comprends la propriété Owner ne change pas quand l'on affecte un Parent. Par contre, le ownership change

    C'est sans doute pourquoi CodeGuard ne donnais pas de fuite de mémoire avec DisplayInterface.
    • Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
    • Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
    • Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon

Discussions similaires

  1. Conception d'une classe parente
    Par VincentB dans le forum Langage
    Réponses: 9
    Dernier message: 24/06/2003, 17h28
  2. Taille d'un TForm à l'état Maximized
    Par Altau dans le forum C++Builder
    Réponses: 2
    Dernier message: 13/06/2003, 12h57
  3. DLL, affichage et parent...
    Par KRis dans le forum Composants VCL
    Réponses: 6
    Dernier message: 13/12/2002, 17h01
  4. [TForm] Ne pas autoriser l'ouverture d'un form
    Par sbeu dans le forum Composants VCL
    Réponses: 6
    Dernier message: 11/10/2002, 11h20
  5. Probleme d'impression avec la méthode TForm->Print()
    Par Kid Icarus dans le forum C++Builder
    Réponses: 13
    Dernier message: 31/07/2002, 14h26

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