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 :

[BCB6] Mettre dans une TForm une autre TForm.


Sujet :

C++Builder

  1. #1
    Débutant
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 62
    Points : 30
    Points
    30
    Par défaut [BCB6] Mettre dans une TForm une autre TForm.
    Bonjour tout le monde.
    J’aimerais savoir si il etait possible avec BCB 6 de faire qu’une TForm soit dans une TForm de base ?

    Si cela est possible par quel biais autre que qt et wxwidget ?

    Merci beaucoup pour vos indications.
    Amitiés.

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Oui c'est tout à fait possible je fait ça courrament pour gérer le contenu dynamique (j'ai BCB 5):

    Il suffit de surcharger le CreateParams:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void __fastcall TfrmViewAwk::CreateParams(TCreateParams &Params)
    {
      TForm::CreateParams(Params);
      Params.Style = WS_CHILD | WS_CLIPSIBLINGS;
      Params.WndParent = frmMain->dwAwk->Handle;
      Params.X = 0;
      Params.Y = 0;
      Params.Width = ...
      Params.Height= ...
    }
    Le host peut-être n'importe quelle TForm ou TPanel ou autre Handle.
    J'instancie les forms dynamiquement en fonction des besoins.

    Voici le code pour l'instanciation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      if (frmViewAwk==NULL) {
        frmViewAwk = new TfrmViewAwk(dwAwk);
        frmViewAwk->Parent = dwAwk;
        frmViewAwk->Show();
      }
    C'est tout, je ne crois pas qu'il en manque (sauf le delete frmViewAwk .
    Je trouve cette façon de faire tout simplement magique, et ça permet aussi d'avoir des objets indépendants ce qui est également un grand plus.

    yarp
    www.senosoft.com

  3. #3
    Débutant
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 62
    Points : 30
    Points
    30
    Par défaut
    Faut t il faire une form en plus de celle de base puis surcharger la form de base ou faut t il que je crée la forme avec le code directement ?

    Par ce que la pour le moment, j’ai un code de base simple

    Unit1.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    Unit1.h

    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
     
    //---------------------------------------------------------------------------
     
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// Composants gérés par l'EDI
    private:	// Déclarations de l'utilisateur
    public:		// Déclarations de l'utilisateur
            __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    Bon jusque la ca me crée une fenêtre simple avec un status bar en bas, j’en aurais besoin plus tard. Mais encore que pour le moment ce n’est pas utile.

    Merci beaucoup pour tes explications et le bout de code du départ.
    Amitiés.

  4. #4
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    J'aurais du être plus clair.
    Tu n'as pas besoin de dériver TForm, il te suffit de déclarer CreateParams dans le header de ta frame (c'est une méthode overridable).

    La classe qui doit être overridée est celle de la child window.

    CreateParams -> child

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class TForm1 : public TForm
    {
    ...
    private:
      void __fastcall CreateParams(TCreateParams &Params);
    }
    Instanciation -> parent

  5. #5
    Débutant
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 62
    Points : 30
    Points
    30
    Par défaut
    Donc en gros, si je me doit de créer une fenêtre dans la fenêtre, je vais dans le Unit.h puis j’instancie celle-ci.

    Mais alors qu’en est t il de son remplissage ?
    Est-ce comme avec une form normal, on place les objets dedans ou alors elle se fait à l’extérieur puis appelé avec le code ?

    Je sait je pose la question de noob mais c’est important par ce qu’il peut en résulté plein de possibilités dans le futur.

    Merci pour ces indications.
    Amitiés.

  6. #6
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Oui c'est une form comme une autre, et tu pose les composants que tu veux dedant. Tu les géreras à partir de cette from là (les évenements et tutti quanti) de toute façon c'est l'inspecteur d'objet qui décide. C'est pour ça que je disais au début que cela crée des objets indépendants, car cela à aussi un effet structurant sur le projet. La classe/frame qui affiche les objets 3D (dans mon soft) encapsule tout le code 3D et seulement elle. En collant un TPaintBox dans la main frame la 3D aurait cotoyé la status bar, les menus, les fonctions (difficile à gérer et on s'éloigne de la philosophie de l'objet).

    ps Je précise que ce ne sera pas Unit1 puisque Unit1 est le nom de la main frame (perso je renomme toujours la main en frmMain c'est plus clair comme ça).

  7. #7
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Sorry, j'avais mal lu pour Unit.
    Ce n'est pas dans Unit.h que tu instancie, mais dans Unit1.cpp bien entendu.
    Il faut que tu écrive un petit framework pour gérer les fenêtre dynamiques (le mot framework est pompeux car le mien se limite à la fonction dont je t'ai mis le code).

    Si on appelle frmMyChild un enfant (frmMyChild doit être enlevé des fenêtres crées dynamiquement par CBuilder - pas obligé mais je ne vois pas l'interêt de la laisser):

    1| initialiser frmMyChild dans le Create : frmMyChild = NULL
    2| quand tu as besoin instancie l'enfant (le code de mon 1er post)
    3| quand tu n'en as plus besoin delete et frmMyChild = NULL

    et tu loop 2 & 3 autant que tu veux. tu peux avoir des enfant différents dans le même host (le parent ou un TPanel du parent) mais pas 2 en même temps dans le même host (ce n'est pas impossible et c'est pour ça que je parlais de framework : il suffit de le coder). Mon code part du principe que chaque host à un et un seul enfant à la fois.

  8. #8
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Je viens de relire ta réponse et j'ai un doute. Tu parlais en intro d'une TForm dans une TForm, donc oui nous avons bien 2 TForm, soir 2 dfm et 2 cpp/h différents. Tu crée chaque TForm avec CBuilder l'une sera la parent, l'autre l'enfant.

    Si tu veux que la TForm child ne soit pas gérée dans un dfm tu peux aussi la créer dynamiquement, no ayes problema. Tout est possible, retiens juste que ce sont 2 objets séparés, chacun vivant sa vie avec sa message loop, et le fiston communique avec son papa sans que tu t'en préoccupe par la magie de Windows et de la VCL.

  9. #9
    Débutant
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 62
    Points : 30
    Points
    30
    Par défaut
    Donc dans ce casla, ma form 1 appelé TForm1 serais parant avec son .h et son .cpp.
    Si je veux en ajouter une, je la crée dehors puis j’inclus en enfant la seconde dans la première.

    Ca me semble logique.
    Aurais tu un exemple à partir code que j’ai donné. Pour que je puisse plus facilement savoir qui interagit avec quoi

    Merci beaucoup de l’aide que tu me donne
    Amitiés.

  10. #10
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    L'exemple est presque tout fait dans le code que je t'ai donné au début. Crée un projet avec 2 fenêtres : ton parent TfrmMain (variable globale d'instance frmMain - en bas du .h), 1 enfant TfrmChild (variable globale d'instance frmChild).

    Dans frmMain tu colle un panel que tu appelle pnlHost et un bouton pour déclencher le processus.
    Il faut que tu mette frmChild à Align = alClient (pour qd elle sera dans pnlHost) - je crois, essaye avec et sans tu verras bien.

    Modifications à apporter dans FFrmMain.h:
    Modifications à apporter dans FFrmMain.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
      // dans le OnCreate:
      frmChild = NULL;
     
      // dans le OnDestroy:
      if (frmChild) delete frmChild;
      frmChild = NULL;
     
      // dans le OnClick du bouton:
      if (frmChild==NULL) {
        frmChild = new TfrmChild(pnlHost);
        frmChild->Parent = pnlHost;
        frmChild->Show();
      }
    Modifications à apporter dans FFrmChild.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    private:
      void __fastcall CreateParams(TCreateParams &Params);
    Modifications à apporter dans FFrmChild.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void __fastcall TfrmChild::CreateParams(TCreateParams &Params)
    {
      TForm::CreateParams(Params);
      Params.Style = WS_CHILD | WS_CLIPSIBLINGS;
      Params.WndParent = frmMain->pnlHost->Handle;
      Params.X = 0;
      Params.Y = 0;
      Params.Width = pnlHost->Width;
      Params.Height= pnlHost->Height;
    }
    Cette implémentation ne fonctionne qu'une fois. Si tu veux créer, supprimer la fenêtre tu ajoute un autre bouton avec le code du destroy.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 59
    Points : 54
    Points
    54
    Par défaut
    question : forme child c bien la forme viewakk ?

    question : le fait de surcharger createparams c'est juste pour que la forme child (ou viewak ) soit bien parametrer cote width ou height ?

  12. #12
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Width et Height sont à mon avis secondaires (il s'agit en fait de créer d'emblée la form à la bonne taille ce qui évite à la from de se retailler, de créer du flicker, et aussi d'avoir une scrollbar . De toute façon frmViewAwk (encore un truc que j'aurais du préciser) est align=AlClient, mais bien sur ça dépends si le host est resizable ou non.

    Le CreateParams est surtout pour donner le style WS_CHILD à l'enfant (oui c'est bien viewAwk, j'ai corrigé dans le code au dessus). En effet WS_CHILD | WS_CLIPSIBLINGS ont un tas de conséquences en matière de messages Windows et de relations parents enfants qui vont donc déterminer le bon comportement de l'ensemble.

    Donc surtout:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      Params.Style = WS_CHILD | WS_CLIPSIBLINGS;
      Params.WndParent = frmMain->pnlHost->Handle;

  13. #13
    Membre habitué

    Profil pro
    Cadre
    Inscrit en
    Mars 2006
    Messages
    132
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre

    Informations forums :
    Inscription : Mars 2006
    Messages : 132
    Points : 168
    Points
    168
    Par défaut
    Il y a un composant de la suite LMD (gratuit ) qui s'appelle TLMDFormDisplayer qui fait ça tout seul, très bien
    Du bon sens tu auras
    Du bon sens tu auras encore
    Du bon sens tu auras toujours
    http://emilien.bresson.free.fr

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 59
    Points : 54
    Points
    54
    Par défaut
    je vais faire des tests dans mon coin mais si je comprend bien
    si dans ma forme main (contenant un panel panel_host) je fais betement
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Tfrm_child* frm = new Tfrm_child(this);
    frm->Parent = panel_host

    et que je ne surcharge pas la methode create param de Tfrm_child,

    alors il se passe quoi ?

    rien ne fonctionne correctement dans ma forme, les evenement ?etc....

    j'essaie de bien comprendre.....

    car moi j'instancie des formes et je les place dans des tabsheet et mes formes ont le comportement désiré...elles fonctionnent tres bien, les onclick des boutons...etc..

    je me lance dans des tests...

  15. #15
    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
    Je ne pense pas que sa existe avec BCB 6, mais avec BDS 2006 il existe un TFrame et c'est vraiment simple à utiliser.
    • 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

  16. #16
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    En fait j'ai agit plus par reflexe que par reflexion, mais WS_CHILD et WS_CLIPCHILDREN sont les styles associés à un enfant, de plus SetParent() ne modifie pas le style de la fenêtre.
    Il me semblait donc logique Windowsement parlant de créer les fenêtres avec le style enfant. Il est possible que la VCL palie elle-même au problème de SetParent mais je trouve ça plus sur comme ça.

  17. #17
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 59
    Points : 54
    Points
    54
    Par défaut
    je ne comprend pas trop en fait l'interet de la surcharge de laméthode...
    désolé...

  18. #18
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Points : 334
    Points
    334
    Par défaut
    Ce n'est pas grave.
    De toute façon ça ne peux pas faire de mal.

Discussions similaires

  1. Mettre deux figures l'une sur l'autre.
    Par mayssaMM dans le forum Tableaux - Graphiques - Images - Flottants
    Réponses: 1
    Dernier message: 07/02/2014, 20h15
  2. [RegExp] Détecter des combinaisons dans une chaine une par une
    Par vermine dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 08/06/2010, 13h22
  3. Réponses: 21
    Dernier message: 20/09/2009, 10h50
  4. Réponses: 2
    Dernier message: 22/02/2008, 10h54
  5. Réponses: 3
    Dernier message: 08/06/2007, 11h24

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