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

Fenêtres et focus


Sujet :

C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut Fenêtres et focus
    Bonjour à toutes et à tous,

    Dans la méthode OnInitDialog d'une boite de dialogue modale, j'ouvre une autre fenêtre non modale qui me permet d'afficher des images ou du texte en relation avec les informations de ma première boite de dialogue.

    J'aimerais que cette fenêtre non modale récupère le focus au détriment de la première boite de dialogue, mais je n'y arrive pas.

    Auriez-vous une suggestion me permettant d'effectuer cette opération?

    J'ai tenté les méthodes SetFocus() ou SetActiveWindow(), mais cela ne donne rien.

    Merci d'avance pour vos réponses.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Salut,

    le principe même d'une modale c'est de garder le focus sur tout le reste tant qu'elle est ouverte... donc pourquoi ne pas fermer la modale si tu veux pas qu'elle ait le focus ? Ou pourquoi créer une modale en ce cas ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Salut,

    Merci pour ta réponse.

    La modale est en fait une fenêtre permettant la navigation dans la seconde fenêtre (avance, recul...) qui sert à la consultation de données stockées en BDD, tout en bloquant l'accès au menu de la MainFrame (ne me demande pas pourquoi ça a été développé comme ça, ce n'est pas moi qui l'ai fait )
    Quand on affiche le second acte et les suivants, suite à un click sur un bouton de la modale, le focus est bien positionné sur la seconde fenêtre.
    Mais à l'ouverture initiale de la modale, c'est toujours la modale qui a le focus.

    J'espère que ces explications t'aideront à mieux comprendre mon problème...

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    Peux tu envisager de modifier la fenêtre principale, ou absolument pas

    Car, comme l'a fait remarquer bousk, une fenêtre modale a des prérogatives qui vont à l'encontre de ton projet.

    Du coup, à condition que cela te soit possible, bien sur, l'idéal serait sans doute de mettre dans ta fenêtre principale un "tag" (à la limite, un simple booléen devrait suffire) destiné à indiquer "l'autorisation" (ou le refus d'autorisation) d'accéder à certains éléments (comme le menu, par exemple).

    Ce "tag" recevrait la valeur indiquant que l'accès est refusé lorsque la boite (qui pourrait dés lors ne plus rien avoir de modale) s'ouvrirait, et remis à sa valeur "accès autorisé" lorsque la boite serait fermée.

    D'ailleurs, si tu utililses Qt (par exemple), il est tout à fait possible d'utiliser les fonctions setDisable(bool) pour forcer la barre de menu à un état (in)actif. Tu pourrais donc travailler en la désactivant juste avant d'ouvrir la boite de dialogue et faire en sorte que cette boite de dialgue émette au moment de sa fermeture un signal, connecté à un slot qui remettra la barre de menu à son état actif.

    A mon sens, c''est la chose la plus cohérente et la plus normale à faire... Mais, vu que tu es visiblement sur un projet dont tu n'es pas le "seul maître à bord", il se peut que des impératifs majeurs, toujours d'actualité aient présidé au choix de créer cette boite sous une forme nodale et / ou qu'il soit "hors de question" d'envisager le moindre changement au niveau de la fenêtre principale (ou encore qu'il n'y ait purement et simplement pas moyen de désactiver la barre de menus, ou que cela ne suffise pas ou ...)

    Le truc, c'est que tu es forcément le seul à être en position de te renseigner sur "ce qui est acceptable", et que ce n'est qu'à partir du moment où nous le saurons que nous pourrons essayer de t'aider efficactement
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Merci pour ta réponse.

    Malheureusement, je ne peux pas modifier le caractère modal de cette boite de dialogue

    Je vais apporter une précision concernant un point sur lequel je n'ai peut-être pas assez insisté, mais j'arrive à donner le focus à ma seconde fenêtre non modale quand j'affiche le deuxième ou le enième enregistrement que je souhaite consulter.
    C'est vraiment uniquement au moment du premier affichage de ma boite de dialogue modale que je n'arrive pas à donner la main à ma seconde boite de dialogue.

    Peut-être puis-je faire l'affichage de ma boite non-modale dans un évènement qui se produirait après le OnInitDialog?
    Existe-t-il un évènement de ce type ou dois-je le gérer moi-même?

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    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 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Il y a pas mal de "détails" à prendre en compte lié au focus dans cette méthode, cf. la documentation :
    https://msdn.microsoft.com/fr-fr/lib...or=-2147217396

  7. #7
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Merci pour ta réponse.

    Malheureusement, cette doc, que je connais, évoque les prises de focus par les contrôles de la boite de dialogue qui est en cours d'ouverture.
    Ca ne m'est donc d'aucune utilité

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    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 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Ca ne m'est donc d'aucune utilité
    Vous avez bien vérifié la valeur de retour et tout le toutime ???

  9. #9
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Oui, j'ai fait différents tests en modifiant la valeur de retour, sans succès

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    On parle de la même chose ?
    Une valeur de retour ça se vérifie, ça ne se modifie pas.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    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 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Une valeur de retour ça se vérifie, ça ne se modifie pas.
    C'est une API à implémenter qui est appelé par les MFC, on doit suivre ses directives.

    @nico_44, montrez votre OnInitDialog, SVP.

  12. #12
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par Bousk Voir le message
    On parle de la même chose ?
    Une valeur de retour ça se vérifie, ça ne se modifie pas.
    OnInitDialog retourne TRUE par défaut. Mais pour jouer avec le focus sur les contrôles de la BDD, elle doit retourner FALSE.
    Tu parles d'autres choses?

    Citation Envoyé par bacelar Voir le message
    C'est une API à implémenter qui est appelé par les MFC, on doit suivre ses directives.

    @nico_44, montrez votre OnInitDialog, SVP.
    Voici mon code (simplifié) :
    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
    BOOL CDlgNavigRegistre::OnInitDialog() 
    {
    	CDialogEx::OnInitDialog();
     
    	m_pFrameWnd = new CFrameWnd();
     
      if (!m_pFrameWnd->CreateEx ( 0, pNomClasse, (const char*)m_TitreVide,
        					WS_OVERLAPPED | WS_EX_CLIENTEDGE | WS_SYSMENU
    						| WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
    						Rect, AfxGetApp()->m_pMainWnd, 0) )
    	{
    		m_pFrameWnd->DestroyWindow();
    	}
      else
      {
        m_pFrameWnd->ShowWindow(SW_SHOW);
     
        m_pFrameWnd->UpdateWindow();
      }
     
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX Property Pages should return FALSE
    }

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    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 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Où settez-vous le focus ???

  14. #14
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Désolé pour le délai de la réponse mais je rentre de vacances ce matin...

    J'ai mis le code d'origine, sans l'instruction pour setter le focus sur la nouvelle fenêtre créée.

    Mes essais ont été faits entre autre avec une instruction m_pFrameWnd->SetFocus() après l'instruction m_pFrameWnd->UpdateWindow()

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    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 069
    Points : 12 113
    Points
    12 113
    Par défaut
    J'ai essayé de reproduire rapidement le problème dans un projet MFC qui traine.
    Mais votre code n'est pas facilement insérable tel-quel.

    En plus, pour la construction de votre fenêtre est très étrange pour des MFC.
    CreateEx, c'est chelou.

    Mais bon, comme c'est une étrange manière de procéder et c'est un endroit encore plus chelou d'instancier une CFrameWnd, cela peut expliquer un comportement étrange.

    Généralement, on utilise une classe dérivée de CWnd et on laisse MFC faire sa tambouille, et on ne crée pas de nouvelles fenêtres dans OnInitDialog.

    Si vous pouvez vous remettre dans un cas plus "standard", ça serait plus simple.

    J'ai fait un copier-coller de ce code dans le projet MFC, ajouté une variable locale du nom de Rect pour rendre compilable le machin, et ramplacer à l'arrache pNomClasse par _T("pNomClasse") et (const char*)m_TitreVide par _T("(const char*)m_TitreVide").
    Comme prévu, en mettant ces noms et titre à l'arrache, CreateEx renvoie une erreur, et m_pFrameWnd->DestroyWindow(); par en exception (comme c'est étrange ).
    Le code n'est donc pas un modèle de robustesse et il manque tout le code qui permettrait d'utiliser directement pNomClasse et m_TitreVide (sans ce putain d'horrible cast tout moisi! ).

    Donc, donnez les extraits de code nécessaire à reproduire le problème, SVP.

  16. #16
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Merci pour votre réponse.

    Je ne vois pas en quoi il est chelou d'instancier une CFrameWnd dans OnInitDialog. A partir du moment où ça fait parti du besoin, je ne vois pas où est le problème...
    Tout comme l'utilisation de CreateEx. Cette méthode existe, c'est pour l'utiliser.

    Quant au code, je peux vous affirmer qu'il est très robuste puisque ça fait des années qu'il tourne sans accroc.

    Je ne peux malheureusement pas être plus complet quant à l'extrait du code, car il est en réalité bien plus complexe que ce que j'ai donné en exemple.
    Je me suis contenté de mettre ce qui permet de créer la fenêtre depuis OnInitDialog, et je ne peux en mettre plus.

    Par contre, j'ai recréé rapidement un petit projet qui génère une CFrameWnd dans OnInitDialog, et qui marche très bien.
    A l'exception du SetFocus...

    Ce projet est en PJ

    Merci de votre aide.
    Fichiers attachés Fichiers attachés

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    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 069
    Points : 12 113
    Points
    12 113
    Par défaut
    J'ai un peu fait joujou avec votre projet.
    Qui est un peu différent du mien, car je n'avais pas compris que la boite de dialogue était la fenêtre "cadre" de démarrage.
    Mais le problème semble être le même.

    Le fait de créer directement un CFrameWnd plutôt qu'une classe qui en dérive, bin, c'est très clairement beaucoup moins simple à utiliser avec de Designer et dans le code, c'est s'enquiquiner pour juste faire du code moins maintenable.
    Mais votre problème n'est pas encore là.

    J'ai des comportements bizarres comme le fait que la fenêtre ne se ferme pas sur l'appuie sur la croix, un affichage d'un truc tout chelou dans ce CFrameWnd, etc...
    Mais c'est vous qui voyez.

    Pour en revenir sur le sujet, votre code m'a permis de valider quelques hypothèses.

    Le fait de retourner "FALSE" et non "TRUE" dans la méthode "CMyAppliTestDlg::OnInitDialog" permet de gérer sans problème le fait qu'un autre contrôle que le bouton "OK" dans la boite de dialogue est le focus en sortie d'initialisation.
    Le truc le plus bateau quoi (et je ne comprends pas pourquoi votre IHM est si bizarre qu'elle ne puisse pas ce suffire de ça).

    Mais pour votre cas, ce n'est pas un contrôle dans la boite de dialogue qui doit avoir le focus.

    Bin, on sort l'artillerie lourde et on s'inspire des choses proposées par le grand Raymond Chen :
    https://blogs.msdn.microsoft.com/old...5-02/?p=29603/

    Donc, la solution à l'arrache que j'en ai déduit, c'est d'ajouter un "PostMessage(WM_APP, 0, 0);" en fin de code de la méthode "CMyAppliTestDlg::OnInitDialog", d'ajouter, via le Designer, une méthode de traitement du message WM_APP et d'y faire le SetFocus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    afx_msg LRESULT CMyAppliTestDlg::OnApp(WPARAM wParam, LPARAM lParam)
    {
    	m_pFrameWnd->SetFocus();
    	return 0;
    }

  18. #18
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2011
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Encore une fois, le projet que j'ai transmis est simplifié à l'extrême. Il n'est là que pour illustrer le problème mais la réalité est bien plus complexe que cela.
    Mais vous comprendrez que pour des raisons de confidentialité et de vulgarisation, je ne peux pas vous transmettre mon projet original.

    Par contre, je vous confirme qu'avec un PostMessage et le traitement qui va bien derrière, ça marche.

    Merci pour votre aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Détecter passage souris sur fenêtre sans focus
    Par ValyGator dans le forum Windows
    Réponses: 1
    Dernier message: 01/02/2012, 07h43
  2. Rafraichir le contenu d'une fenêtre au focus
    Par jpclabaux dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 15/06/2010, 16h18
  3. fenêtre sans focus au chargement
    Par psgkiki dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 30/03/2008, 09h43
  4. Afficher une fenêtre sans focus
    Par kmaniche dans le forum C++Builder
    Réponses: 5
    Dernier message: 05/02/2007, 19h40
  5. [eclipse][plugin] Comment avoir une fenêtre avec focus
    Par relivio dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 07/04/2004, 15h54

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