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.
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.
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:
Le host peut-être n'importe quelle TForm ou TPanel ou autre Handle.
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= ... }
J'instancie les forms dynamiquement en fonction des besoins.
Voici le code pour l'instanciation:
C'est tout, je ne crois pas qu'il en manque (sauf le delete frmViewAwk .
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(); }
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
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
Unit1.h
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) { } //---------------------------------------------------------------------------
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.
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
Merci beaucoup pour tes explications et le bout de code du départ.
Amitiés.
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
Instanciation -> parent
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); }
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.
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).
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.
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.
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.
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// rien
Modifications à apporter dans FFrmChild.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 // 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.cpp:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 private: void __fastcall CreateParams(TCreateParams &Params);
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.
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; }
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 ?
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;
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
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...
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
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.
je ne comprend pas trop en fait l'interet de la surcharge de laméthode...
désolé...
Ce n'est pas grave.
De toute façon ça ne peux pas faire de mal.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager