Communication entre fenêtre

Communication entre fenêtre - C++ - Programmation

Marsh Posté le 21-07-2004 à 10:00:08    

Salut =)
bon une p'tite question facile pour vous échauffer ce matin :) : comment faire pour récupérer les données d'une fenêtre modale qd on la ferme? Est-ce que surcharger la fonction EndDialog pourrait être une soluce? ++
EnJoY It =))))

Reply

Marsh Posté le 21-07-2004 à 10:00:08   

Reply

Marsh Posté le 25-07-2004 à 00:05:26    

un Ex :
 
MaFenetre = new Fenetre
MaFenetre.AfficherModal
val_a = MaFenetre.Get_Valeur_a()
val_b = MaFenetre.Get_Valeur_b()
delete MaFenetre

Reply

Marsh Posté le 28-07-2004 à 09:44:19    

Salut indice =) et merci de m'avoir répondu! j'avais finalement trouvé une autre soluce. j'ai déclaré dans la fenêtre fille un pointeur sur la fenêtre mère pour pouvoir accéder aux contrôles :

Code :
  1. void CCEquipeDlg::OnBnClickedButton1()
  2. {
  3. CConditionnementDlg *pDlg=( CConditionnementDlg *)GetParent();
  4. CString tmp;
  5. GetDlgItemText(IDC_LISTEQUIPE,tmp);
  6. pDlg->SetDlgItemText(IDC_EQUIPE,tmp);
  7. GetDlgItemText(IDC_COMBO1,tmp);
  8. pDlg->SetDlgItemText(IDC_CONDUCTEUR,tmp);
  9. EndDialog(1);
  10. }


car si je ne me trompe pas, de la façon dont tu le fais, étant donné que c'est une fenêtre modale, il n'executera pas le code après DoModal() tant que la fenêtre n'est pas fermée. et nous n'avons alors plus accès aux contrôles.  
++ EnJoY It =))))

Reply

Marsh Posté le 28-07-2004 à 10:36:49    

GetParent c'est mal. Ton controle enfant n'est pas réutilisable, si tu modifies le parent il faut modifier ses enfants. Un enfant ne devrait pas se préocuper de ses parents.
Après je comprends pas ta remarque :

Citation :

étant donné que c'est une fenêtre modale, il n'executera pas le code après DoModal() tant que la fenêtre n'est pas fermée. et nous n'avons alors plus accès aux contrôles


Quels contrôles ? Et si ce comportement te plait pas, pourquoi avoir choisi une boite modale ?
Si tu as besoin de données, demande dans ton constrcuteur une structure remplie par le parent qui contient tout ce dont tu as besoin. En fin d'exécution, le parent récupère cette structure et met éventuellement ses données à jour :

Code :
  1. // code du parent
  2. struct EditInfo infos;
  3. this->GetDlgItemText(IDC_LISTEQUIPE, infos.ListEquipes);
  4. this->GetDlgItemText(IDC_COMBO1, infos.Conducteur);
  5. CCEquipeDlg dlg( this, info );
  6. if ( dlg.DoModal() == MB_OK )
  7. {
  8.     // bouton Ok, appliquer les changements
  9.     this->SetDlgItemText(IDC_LISTEQUIPE, dlg.GetInfos().ListEquipes);
  10.     this->GetDlgItemText(IDC_COMBO1, dlg.GetInfos().Conducteur);
  11. }


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 28-07-2004 à 12:16:35    

'lut hello =)
je vais te demander qq précisions, car je débute et j'ai qq pb. je n'ai pas voulu créer de structure vu que je ne n'ai que 2 variables à récupérer. j'ai essayer de les passer dans le constructeur. elles st bien arrivées, mais ensuite je veux les modifier quand je clique sur "OK" :

Code :
  1. //Voici le constructeur :
  2. CCEquipeDlg::CCEquipeDlg(CWnd* pParent /*=NULL*/,CString &equipe,CString &conducteur):CDialog(CCEquipeDlg::IDD, pParent)
  3. {}
  4. //et la fonction associée au bouton :
  5. void CCEquipeDlg::OnBnClickedButton1()
  6. {
  7. GetDlgItemText(IDC_LISTEQUIPE,equipe);
  8. GetDlgItemText(IDC_COMBO1,conducteur);
  9. EndDialog(1);
  10. }


or quand je compile il me met qu'equipe et conducteur sont deux identificateurs non déclarés. en fait si je comprends bien il n'existe que le tps du constructeur puis sont détruits, nan? comment faire alors? ça marche mieux avec des structures? ++

Reply

Marsh Posté le 28-07-2004 à 12:28:46    

dans CEquipeDlg (déclaration de la classe), ajoutes:
CString equipe;
CString constructeur;
 
Ensuite

Code :
  1. CCEquipeDlg::CCEquipeDlg(CWnd* pParent /*=NULL*/,CString &e,CString &c):CDialog(CCEquipeDlg::IDD, pParent), equipe(e), constructeur(c)
  2.   {}


parce que pour le moment tu passes 2 arguments, mais t'en fais rien, ils n'existent plus dans ton objet à partir du moment ou tu sors du constructeur
 
(et qu'est ce que tu parles de structures? c'est du C++, donc t'as des classes, CCEquipeDlg est une classe donc tu crées equipe et constructeur en tant que membres de CCEquipeDlg stou)


Message édité par masklinn le 28-07-2004 à 12:29:56
Reply

Marsh Posté le 28-07-2004 à 12:37:20    

HelloWorld a écrit :

demande dans ton constrcuteur une structure remplie par le parent qui contient tout ce dont tu as besoin. En fin d'exécution, le parent récupère cette structure et met éventuellement ses données à jour :

Code :
  1. // code du parent
  2. struct EditInfo infos;
  3. this->GetDlgItemText(IDC_LISTEQUIPE, infos.ListEquipes);
  4. this->GetDlgItemText(IDC_COMBO1, infos.Conducteur);



dc voilà. sinon pour ta solution, ok je rajoute des variables membres à la classe CequipeDlg. c'est ce que je pensais faire, mais je ne savais pas les initialiser. donc apparement c'est ds le constructeur. qu'est-que ça fait exactement quand tu fais :

Code :
  1. equipe(e)


bon je vais manger on verra ça le ventre plein! ++

Reply

Marsh Posté le 28-07-2004 à 12:57:27    

equipe(e) ca appelle le constructeur de equipe (CString) en fournissant comme paramètre un autre CString (e), donc en fait ca copie "e" dans "equipe"
(par contre je sais plus si il faut utiliser des virgulles ou un autre truc)
 
si tu veux faire plus compréhensible (mais moins classe), tu les mets pas et tu écrit

Code :
  1. CCEquipeDlg::CCEquipeDlg(CWnd* pParent /*=NULL*/,CString &e,CString &c):CDialog(CCEquipeDlg::IDD, pParent)
  2. {
  3.     this->equipe = e;
  4.     this->constructeur = c;
  5. }


un peu plus clair, mais tellement moins sex  :sol:


Message édité par masklinn le 28-07-2004 à 12:57:48
Reply

Marsh Posté le 28-07-2004 à 14:11:15    

lol, c'est clair que c'est moins impressionnant ;-) en tout k, ce st bien des virgules, ça marche. mais par contre ça ne résout pas mon pb originel... parce qu'en fait je voudrais me servir des variables equipe et conducteur dans la fenêtre parent, et non l'inverse. or quand je fais ce que tu m'as dit, c'est pour se servir des variables dans la fenêtre enfant. le truc, c'est qu'en le user arrive, il doit sélectionner son n° d'équipe et le nom du conducteur de ligne (c'est une appli pour de la production indutrielle). or les valeurs de equipe et de conducteur dans la fenêtre parent n'ont pas changées. dc comment faire? je compte sur toi masklinn, car tu as l'air d'être un adepte du code stylé ;-)

Reply

Marsh Posté le 28-07-2004 à 16:34:24    

Ben une fois ton dialog exécuté, c'est le parent qui se met à jour.

Citation :

Code :
  1. if ( dlg.DoModal() == MB_OK )
  2.   {
  3.         // bouton Ok, appliquer les changements  
  4.         this->SetDlgItemText(IDC_LISTEQUIPE, dlg.GetInfos().ListEquipes); 
  5.         this->GetDlgItemText(IDC_COMBO1, dlg.GetInfos().Conducteur);
  6.   }



Passer par une strcuture c'est mieux car elle caractérise l'état de ton programme (avec les MFC tu as le Document-Vue : la strcuture est le document, et chaque fenêtre (parent, dlg, ...) constitue une vue).
Il suffit que chacune de tes fenêtre soit capable de s'initialiser à partir de ta struct (qui contient toutes les données de ton programme => le document) pour ne plus avoir qu'à faire passer ce document entre les vues qui le visualise / le modifient.
Si par la suite tu veux sauvegarder des réglages, tu n'a qu'à sérialiser ta struct et c'est fini.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 28-07-2004 à 16:34:24   

Reply

Marsh Posté le 28-07-2004 à 16:55:27    

faut faire comme HelloWorld te dit depuis le début:
 
dans CEquipeDlg tu crée des fonctions d'accès aux membres de la classe (parce que accéder directement aux variables saitraimal), soit Set+Get soit Get renvoyant une référence (que tu lis ou modifie directement en fonction de ce que tu veux en faire), et après tu lances ta fenêtre en modal, et quand la fenêtre est fermée (fin du DoModal()) tu accèdes aux données de la fenêtre fille grâce à tes fonctions d'accès.
 
Il faut simplement penser à n'appeler le destructeur de la fenêtre fille qu'APRES avoir récupéré tes valeurs (sinon tu essaies d'accéder à des données déjà détruites).


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 28-07-2004 à 17:12:07    

bon tu vas me dire que je suis chiant, mais j'aimerais bien comprendre un truc sans les structures. bon c'est normal que les variables ne soient pas modifiées, car on passe seulement les valeurs. je vais essayer en passant les adresses des CString. sinon que signifie "sérialiser une structure"??? (ben oui désolé je ne connais pas ce terme).

Reply

Marsh Posté le 28-07-2004 à 17:25:22    

désolé je n'avais pas vu ton dernier message masklinn. alors j'ai pas tout compris... si je reprends ta dernière phrase, ça veut dire que je peux appeler le destructeur après d'avoir fait le EndDialog()??? si oui est-ce qu'on pt encore avoir accès aux contrôles de la fenêtre fille? parce que ça résoudrait tous les pb!

Reply

Marsh Posté le 28-07-2004 à 17:31:33    

Il veut juste dire qu'il ne faut pas détruire ton objet avant d'avoir récupéré les valeurs, genre :

Code :
  1. CCEquipeDlg * dlg = new CCEquipeDlg( this );
  2. dlg->DoModal();
  3. delete dlg; // faut être con quand même
  4. dlg->GetValeurX(); // badaboum


 
Sérialiser, ça veut simplement dire transformer tes données (ta stuct) en un flux, c.a.d une chaine de carcatères par exemples, que tu peux lire/écrire dans un fichier par exemple (fichier de sauvegarde...).
Les MFC fournissent des facilités pour cela il me semble, mais je n'en sais pas plus.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 28-07-2004 à 17:34:27    

je ne connais pas les instructions set et get. à quoi servent-elles exactement? désolé de poser toutes ces questions, mais bon j'aimerais bien comprendre! =)

Reply

Marsh Posté le 28-07-2004 à 17:37:02    

HelloWorld a écrit :

Code :
  1. CCEquipeDlg * dlg = new CCEquipeDlg( this );
  2. dlg->DoModal();
  3. delete dlg; // faut être con quand même
  4. dlg->GetValeurX(); // badaboum


 


aïe! ùais je ne déclare pas mon objet CEquipeDlg en dynamique... il vaudrait ou pas?

Reply

Marsh Posté le 28-07-2004 à 17:39:26    

destynov@ a écrit :

je ne connais pas les instructions set et get. à quoi servent-elles exactement? désolé de poser toutes ces questions, mais bon j'aimerais bien comprendre! =)


ce sont ce qu'on appelle des accesseurs, qui te permettent d'accéder aux données privées d'une classe de manière sécurisée.
ce sont des fonctions que tu dois écrire toi même :

Code :
  1. class machin
  2. {
  3.    private:
  4.       int a;
  5.    public:
  6.       machin();
  7.       int getA(void);
  8.       void setA(int value);
  9. };
  10. machin::machin()
  11. {
  12.    a = 3;
  13. }
  14. int machin::getA()
  15. {
  16.    return a;
  17. }
  18. void machin::setA(int value)
  19. {
  20.    a = value;
  21. }



---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 28-07-2004 à 17:48:15    

destynov@ a écrit :

je ne connais pas les instructions set et get. à quoi servent-elles exactement? désolé de poser toutes ces questions, mais bon j'aimerais bien comprendre! =)


Quand tu crées une classe, tu peux avoir des membres et méthodes privés et publics.
 
Pour des raisons de sécurité et de "fiabilité", on a tendance à empêcher l'accès direct aux variables (membres), que l'on met donc en privé et on crée des méthodes publiques qui permettent d'accéder indirrectement aux variables (et te permettent accessoirement de clarifier ton code et surtout de vérifier les valeurs d'E/S de manière à ce qu'on ne puisse pas donner des valeur erronées à tes variables (genre coller 2574 dans un int censé rester entre 0 et 10). De plus, ca permet de planquer une partie du fonctionnement interne de la classe tout ca, en tout cas c'est nécessaire.
 
 
Après, t'es pas obligé d'utiliser des pointeurs sur ton objet (new), si tu ne le fait pas t'as pas à t'inquiéter au sujet de la destruction (théoriquement) mais l'objet disparait quand on sort de la fonction (pas gênant pour une fenêtre modale, normalement t'en as plus besoin une fois sorti de la fonction, beaucoup plus gênant pour une fenêtre non modale ;))


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 28-07-2004 à 17:51:55    

oki merci harkonnen =) alors résumons! il faut que je déclare une fonction qui me permettent d'accéder (ah c'est pr ça qu'on les appelle des accesseurs!!! =)) à ma structure dans la classe CEquipeDlg, c'est bien ça? en fait c'était pas si compliqué que ça, mais quand on ne connaît pas les structures, ni les accesseurs, (en gros ni le c++...) c'est pas facile! en tout k merci pour tout les gars (surtout pour la patience!) =))) ++

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed