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++/CLI Discussion :

C++/CLI : gestion de fenêtres filles à partir d'une fenêtre mère


Sujet :

C++/CLI

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut C++/CLI : gestion de fenêtres filles à partir d'une fenêtre mère
    Bonjour,

    Pose de mon problème:

    J'ai une application avec une Form que j'appelle "mère"; cette Form contient une listView avec différents Items.

    Quand l'utilisateur fait un doubleClick sur un Item de la listView l'application ouvre une fenêtre que j'appelle "fille".

    Cette fenêtre "fille" permet à l'utilisateur d'agir sur les paramètres de l'Item sélectionné.

    L'utilisateur doit pouvoir avoir plusieurs fenêtres "filles" ouvertes en même temps ...

    Jusque là pas de problème

    Par contre c'est là que mon problème arrive:

    Quand l'utilisateur fait un doubleClick sur un Item qui possède déjà une fenêtre fille ouverte, je voudrais que cette fenêtre soit réveillée pour attirer l'attention de l'utilisateur.

    Le problème est que chaque fenêtre "fille" une fois ouverte vit sa vie seule et que l'application qui a lancé les fenêtres "fille" connaît tout juste leur existence, mais ne sait rien d'autre ..

    Je n'ai aucune idée de comment faire ça proprement.

    Si quelqu'un pouvait m'aiguiller ce serait sympa.

    Bonne journée

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Ta fenêtre "fille" (en fait, plutôt une fenêtre "owned") c'est une Form^ (ou classe descendante de Form) également, non?

    Tu peux mémoriser sa référence dans ta Form principale une fois qu'elle est ouverte, et interagir avec lors d'un clic...

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 210
    Points : 12 381
    Points
    12 381
    Par défaut
    WinForms, je suppose.
    La méthode Activate de la classe Form.
    http://msdn.microsoft.com/en-us/libr...v=vs.110).aspx

    Vous faites en sorte que dans le constructeur de la classe du "sous" formulaire, il appel une méthode d'enregistrement de l'objet "formulaire racine".
    Dans les méthodes Close du "sous" formulaire, vous appelez une méthode de désenregistrement.
    La classe racine n'a qu'a stocker ces références dans une table d'association et appeler la méthode Activate sur ces références au moment opportun.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Merci Bacelar,

    Je regarde ça dès que je peux.

    Avant d'ouvrir la Form "fille" l'application "mère" stocke des données dans un singleton qui sert de boite aux lettres. La Form "fille" s'ouvre et récupère les données, puis vit sa vie indépendamment.

    Toutes les Forms "fille" sont ouvertes à partir du même évènement ItemActivate de la listView et de la même façon.

    Dans le traitement de l'évènement je recherche d'abord quel Item a été cliqué dans la listView, je stocke les données correspondante à l'Item dans le singleton, puis je lance la fenêtre fille par ces 2 lignes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     Formulaire ^ Form2 = gcnew Formulaire;
     Form2->Show (this);
    La fenêtre fille en s'ouvrant récupère ses données dans le singleton, puis fonctionne comme une fenêtre indépendante.

    L'utilisateur peut alors double cliquer sur un autre Item de la listView et disposer d'une seconde fenêtre, puis d'une 3ième et ainsi de suite.

    Bonne soirée

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 210
    Points : 12 381
    Points
    12 381
    Par défaut
    Pourquoi passer par un singleton.
    Le plus simple est de passer par des paramètres du constructeur.
    Passez en paramètre aussi le formulaire parent.
    Dans le constructeur de votre Form Fille, enregistrez la en appelant un méthode dédiée de votre Form principale.
    Dans le Close de la fenêtre de vos fenêtres secondaire, vous appelez la méthode de désenregistrement de votre Form principale.
    ...
    Dans la méthode d'enregistrement de votre Form principale, vous associez la Form secondaire à une clé dans une table d'association.
    Dans la méthode de désenregistrement de votre Form principale, vous supprimez cette association.

    Dans ItemActivate, on commence par lire la table d'association et faire un Activate sur le formulaire secondaire s'il est enregistré, sinon on crée le formulaire secondaire, en passant en paramètre les informations nécessaires.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Pourquoi passer par un singleton.
    C'est parce que je ne sais pas faire autrement.


    Citation Envoyé par bacelar Voir le message
    Le plus simple est de passer par des paramètres du constructeur.
    Passez en paramètre aussi le formulaire parent.
    Je ne me suis jamais trop penché sur la façon utilisée par Visual pour construire les Form ...
    Je me contente d'utiliser l'interface graphique.

    J'ai beaucoup programmé en assembleur, puis en Fortran et en C et la programmation objet reste encore une science un peu obscure pour moi.

    Merci, je vais essayer de comprendre mais pour l'instant il m'a fallu déplacer mes priorités.

    Bonne journée.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 210
    Points : 12 381
    Points
    12 381
    Par défaut
    Le passage de paramètres, c'est comme en C.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Bonjour,

    Aujourd'hui j'ai trouvé 5 minutes pour me replonger sur ce problème.

    J'ai créé une Form1 puis une seconde Form2.

    Dans la forme 1 j'ai ajouté un bouton que j'ai associé à ce bout de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    i++;
    Form2^ f2 = gcnew Form2();
    f2->Show (this);
    f2->clef = i;
    i est un entier.

    Dans Form2 j'ai rajouté une variable :

    et une textbox + un bouton associé à:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
    {
    	 textBox1->Text = clef.ToString();
    }

    Quand j'ouvre plusieurs fenêtres Form2, je visualise bien 1, 2, 3, etc ... dans la textbox. Donc mes fenêtres fille récupèrent bien leur clef respective.

    Mais je ne vois toujours pas comment on peut réactiver une fenêtre déjà instanciée ...

    Exemple : je sais que la fenêtre qui a la clef n° 3 existe déjà, comment puis je la réveiller?

    De même si je ferme la fenêtre 3 comment avertir la Form1 de cet évènement?

    Bonne soirée.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Dans ItemActivate, on commence par lire la table d'association et faire un Activate sur le formulaire secondaire s'il est enregistré, sinon on crée le formulaire secondaire, en passant en paramètre les informations nécessaires.

    En fait c'est ça que je ne vois pas comment faire ...

    Vu de Form1 toutes les Form2 sont les mêmes et comment en réveiller une plutôt qu'une autre ...

    Bonne soirée

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    private:
    	Dictionary<int, Form2^> formulairesOuverts;

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    private:
    	Dictionary<int, Form2^> formulairesOuverts;
    Bonjour Médinoc,


    Merci.
    Vu mon niveau c'est un peu laconique, mais cela m'a servi à découvrir des choses.

    J'ai découvert qu'il existe une propriété qui s'appelle OwnedForms (VOIR ICI)

    Mais je ne comprends pas bien ...

    Je pense qu'il faut créer une Array (peut-être ce que vous appelez Dictionnary?), mais où et comment la déclarer? c'est toujours mon problème.

    Ensuite je pense qu'à chaque création de Form il faut faire un AddOwnedForm pour mettre la Form dans le dictionnaire.

    Est ce que je suis sur la bonne voie?

    Bonne journée

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Je ne connaissais pas les Owned Forms, je voulais juste te dire de simplement mémoriser les formulaires que tu crées dans une variable membre, plutôt que chercher à les "retrouver" quand tu en as besoin.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Je ne connaissais pas les Owned Forms, je voulais juste te dire de simplement mémoriser les formulaires que tu crées dans une variable membre, plutôt que chercher à les "retrouver" quand tu en as besoin.
    C'est comme cela que je l'avais compris ..

    J'ai réussi à faire ce que je voulais, mais je ne sais pas si la méthode utilisée est très professionnelle.

    J'ai fait une List de mes Form...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private:
    List<Form^> ^ mes_formes;
    .
    .
     
    mes_formes = gcnew List<Form^>; 
    .
    .
    Form2 ^f2 = gcnew Form2();
    mes_formes->Add(f2);
    f2->Show(this);
    Ensuite en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mes_formes[i]->Focus();
    J'arrive à redonner le focus à la forme qui m'intéresse

    J'arrive aussi à la modifier (taille, titre, etc ...)

    Maintenant si cette méthode tient la route, il faut que je trouve comment une Form fille peut alerter la Form mère du fait qu'elle a été fermée par l'utilisateur.

    Bonne journée.

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Tu écoutes l'événement FormClosed...

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Tu écoutes l'événement FormClosed...
    Mais comment et avec quoi?

    Il faudrait un contrôle dans Form1 qui s'active lors d'un FormClosed d'une des Forms

    Je ne vois pas du tout comment faire ça.

    Au fait tu ne m'as pas dit si ma solution avec la List est une solution acceptable.

    Bonne soirée

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 210
    Points : 12 381
    Points
    12 381
    Par défaut
    A oui, je n'avais pas pensé aux events publiés par les Formulaires.
    Ca simplifie le code de gestion de cette fonctionnalité mais l'utilisation des delegates en C++/CLI pour une personne venant du C++ standard, c'est loin d'être naturel.

    L'utilisation de la liste, c'est la bonne voie. Le problème, c'est que vous devez utilisez un identifiant et non un indice. Si vous voulez ouvrir une Form fille pour l'item de clef "2" sans ouvrir l'item de clef "1", vous avez un problème avec une list, car il aura plein de trou.
    On utilise donc une autre structure qui associe une clé à un objet, c'est le "Dictionary<int, Form2^> " de Médinoc.
    http://msdn.microsoft.com/en-us/libr...v=vs.110).aspx
    C'est comme votre liste, sauf que les objets ne sont pas stockés les uns derrière les autres, mais associe une clé à un objet.

    en ajoutant une propriété public m_cle à votre classe de formulaire secondaire, le code, avec utilisation de delegate sur l'event FormClosed.

    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
    private:
    Dictionary<int, Form2^> formulairesOuverts;
    .
    .
     
    formulairesOuverts = gcnew Dictionary<int, Form2^>; 
    .
    .
    .
    if(!formulairesOuverts->ContainsKey(clef))
    {
        formulairesOuverts->Add(clef,gcnew Form2(clef));
        ((Form2^)(formulairesOuverts[clef]))->FormClosed += gcnew System::Windows::Forms::FormClosedEventHandler(this, &Form1::Unregister);
    }
    formulairesOuverts[clef]->Show();
     
    ...
    private: void Unregister(System::Object^  sender, FormClosedEventArgs^ e)
    {
        if(formulairesOuverts->ContainsValue((Form2^)(sender)))
       {
          formulairesOuverts->Remove(((Form2^)(sender))->m_cle);
       }
    }
    Mais je pense que l'utilisation des delegates va poser des problèmes de threading.

    Donc, un approche plus safe est de faire un appel à la méthode Unregister depuis le formulaire secondaire, il suffit d'utiliser le champ Owner du formulaire pour retrouver le formulaire principale et de le caster en Form1.

    P.S.:"OwnedForms", c'est une mauvaise voie (ou très indirecte, mais tout les chemins mènent à Rome ).

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 210
    Points : 12 381
    Points
    12 381
    Par défaut
    J'ai oublié de dire que souvent les contrôles .NET multi-lignes ont des propriétés avec des Noms type "Tags" pour chaque ligne qui sont souvent utilisées pour stocker ces références.

    Dans notre cas, cela implique que nous n'aurions plus de champ dictionnaire "formulairesOuverts", mais que l'ont stockerait les références directement dans le champ "Tags" de la ligne du control.

  18. #18
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Le cast n'est pas nécessaire sur cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        ((Form2^)(formulairesOuverts[clef]))->FormClosed += gcnew System::Windows::Forms::FormClosedEventHandler(this, &Form1::Unregister);

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Bonsoir et merci à tous deux ...

    Bon c'est vrai que je suis un peu (beaucoup) dans le brouillard, ..

    J'ai essayé de compiler le bout de code de Bacelar, ..

    le compilateur me jette sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(!formulairesOuverts->ContainsKey(clef))
    avec le message :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error C2819: type 'System::Collections::Generic::Dictionary<TKey,TValue>' does not have an overloaded member 'operator ->'
    il me jette aussi sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    formulairesOuverts->Add(clef,gcnew Form2(clef));
    avec le message :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error C2232: '->System::Collections::Generic::Dictionary<TKey,TValue>::Add' : left operand has 'class' type, use '.'
    Et il me jette aussi dans Unregister avec des messages similaires

    J'ai essayé divers trucs mais toujours les erreurs .. je ne comprends parce que si on regarde les exemples de Microsoft cela paraît correct ..

    Bonne soirée

  20. #20
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Désolé, il y avait une erreur dans la ligne que j'ai proposée: Il manquait un chapeau:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dictionary<int, Form2^>^ formulairesOuverts;

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 3
    Dernier message: 10/05/2012, 15h35
  2. Réponses: 1
    Dernier message: 26/12/2010, 20h29
  3. Actualiser une fenêtre parent à partir d'une popup
    Par scorian dans le forum WebDev
    Réponses: 1
    Dernier message: 22/08/2007, 10h50
  4. Controler une fenêtre a partir d'une autre fenêtre
    Par Invité dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 24/08/2006, 22h21
  5. Afficher une Fenêtre MDI à partir d'une DLL
    Par FredericB dans le forum C++Builder
    Réponses: 2
    Dernier message: 06/12/2005, 17h58

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