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

MFC Discussion :

Detecter souris sur CButton


Sujet :

MFC

  1. #1
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut Detecter souris sur CButton
    Bonjour,

    Je voudrais en effet pouvoir détecter lorsque l'utilisateur clic sur un bouton mais sans relacher le bouton de la sourie, et effectuer un traitement jusqu'a ce qu'il relâche le bouton. C'est pour effectuer les fonctions 'Rembobiner' et 'avance rapide' pour un player audio.

    Etant donné que le OnBnClick() ne se déclanche que lorsque l'utilisateur à relâché le bouton je ne peut pas l'utiliser.

    J'ai pensé récupérer les coordonnées de la sourie et détecter lorsqu'il y a un clic dans le rectangle correspondant au bouton, mais comment récupérer le rectangle de mes CButton (CBitmapButton en fait) pour tester si mon curseur est à l'intérieur ? Et est-ce une bonne solution ?

    Moi qui ai l'habitude de faire du java je trouve assez bizarre qu'il n'y ai pas les évènements classique comme OnMouseDown, OnMouseUp, OnMouseMove etc sur les boutons. C'est pas très pratique je me demande pourquoi ce n'est pas géré.

    Je suis sous Visual C++ 2005 MFC Application boite de dialogue.

    Merci à vous.

  2. #2
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    Bonjour,

    sauf erreur de ma part, c'est traité, car CButton est dérivé de CWnd.

    en interceptant le message WM_LBUTTONDOWN du CButton en question
    (remplacer L par R pour le bouton droit
    DOWN par UP pour le relachement du bouton, ou DBLCLK pour un double-clic),
    tu devrais traiter cet évènement

    Philippe

  3. #3
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Merci Philippe320.

    Mais comment puis-je intercepter ce message ?

    Je suis débutant en MFC.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Il faut subclasser le bouton.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Je n'y arrive pas.
    Les exemples sur le net ne sont pas très explicatifs...

    Vous n'auriez pas un bon lien, un tuto, un exemple ?

    Merci.

  6. #6
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    Il faut créer une nouvelle classe (Project > Add Class),ensuite choisir MFC class,
    l'appeler CMonBouton par exemple, en le dérivant de CButton ( base class)
    définir les fichiers (MonBouton.cpp et MonBouton.h)

    Ensuite, dans les propriétés de cette classe (choisis Class View pour voir ton projet classes par classes, tu as le message WM_LBUTTONDOWN : tu double-cliques dessus, et il te créer automatiquement la procédure chargée du traitement de ce message.

    Dès que tu appuyeras sur le bouton gauche sur le bouton en question, tu arriveras à cet endroit du code.

    Il faut aussi lui dire que le bouton que tu as dessiné dans la ressource est du type CMonBouton (bouton droit et Propriétés)

    Voilà, en gros, j'sais pas si c'est très clair, redemande moi sinon

    A+
    Philippe

  7. #7
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Tous ça pour ça. Ils ont pas pu faire plus compliqué je pense.
    Pourquoi ne pas avoir gérer ça comme le OnBnClick() ...

    Sinon je ne comprend pas bien, il faut que je déclare mon bouton de type CMaNouvelleClass ? et non plus CBitmapButton

    Parceque ça ne génère rien à part des messages d'erreurs.

    Et comment j'accède à tous mes attributs/fonctions de ma classe CMaClasseDlg depuis ma nouvelle classe ? Je ne peut pas créer d'instance de ma classe Dlg...


    Bizarre cette affaire.

  8. #8
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    pour les exemples, regarde http://www.codeguru.com/cpp/controls...cle.php/c2097/

    c'est le même principe : la fonction OnMouseMove est surclassée pour définir le comportement en cas de mouvement de la souris

    d'ailleurs, le site est une mine d'or pour la personnalisation des interfaces et pour comprendre les MFC


    oui, tu déclares la classe dérivée de CBitmapButton

    pour accéder à la boite de dialogue, à vérifier, un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CDialog* maDialogue = (CDialog*)this->GetParent();
    tu as donc un pointeur vers le parent du bouton, donc vers la boite de dialogue (regarde, c'est ce qu'ils font dans le code indiqué plus haut)

    avec maDialogue-> , tu peux accéder aux fonctions de CDialog



    Philippe

  9. #9
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Hm je n'ai pas accès aux fonctions et aux attributs que ce soit par :
    CDialog* pParent = (CDialog*)this->GetParent();
    ou
    CWnd* pParent = GetParent();

    pParent-> me donne bien une liste de fonctions mais celles définies dans ma classe Dlg n'apparaissent pas, les attributs non plus.

    Je suis perdu là.

    Merci pour tes réponses rapides.

  10. #10
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    désolé, mais je ne comprends pas très bien ta réponse:

    j'ai testé l'exemple de CodeGuru (après conversion automatique de VS2005):
    c'est exactement ce que tu recherches

    j'ai même ajouté une ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void CTrickButton::OnMouseMove(UINT nFlags, CPoint point) 
    {
        CWnd* pParent = GetParent();
        if (!pParent) pParent = GetDesktopWindow();
     
    // ligne ajoutée
    	pParent->SetWindowText("ceci est un test");
     
        CRect ParentRect;                                   // Parent client area (Parent coords)
        pParent->GetClientRect(ParentRect);
    le titre de la boite de dialogue est modifié, preuve que pParent pointe bien vers cette boite, donc vers tout ce qu'elle contient.


    autre solution, inversée, la boîte de dialogue donne son adresse au CMonBouton (dans lequel tu as un pointeur CDialog* parent)
    et à l'init, CDialog initialise parent avec sa propre adresse
    (c'est à mon avis moins propre)

    Philippe

  11. #11
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Merci d'avoir testé.

    J'ai bien accès à SetWindowText() et à d'autres fonctions qui agissent sur ma boite de dialogue.

    Mais je n'ai pas accès aux fonctions qui gère les actions de ma boite de dialogues comme OnBnClickedBtnSuivant() etc, ni aux attributs déclarés dans la classe Dlg.

    En tous cas je trouve ça bien compliqué, ça aurait pris 2 lignes en Java.

  12. #12
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    il faudrait nous donner ton code, car OnBnClickedBtnSuivant() étant une fonction que tu as créée, on ne peux pas deviner comment tu l'as déclarée etc..
    le problème vient peut-être de là

    Philippe

  13. #13
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Mes méthodes OnBnClickedSuivant() sont des méthodes que je génère depuis l'interface graphique en faisait clic droit -> ajouter un gestionnaire d'évènements -> BN_CLICKED sur la classe CPlayerDlg.

    J'ai donc simplement dans le BEGIN_MESSAGE_MAP :
    ON_BN_CLICKED(IDC_BTN_SUIVANT, &CAudioPlayerDlg::OnBnClickedSuivant)

    dans le .h
    public:
    afx_msg void OnBnClickedSuivant();

    dans le .cpp :
    void CAudioPlayerDlg::OnBnClickedSuivant()
    {
    ...
    }

    J'ai aussi des variables globales dans ma classe CPlayerDlg qui ne sont pas accessible depuis ma nouvelle classe, même en les déclarant static.

  14. #14
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Je voudrais en effet pouvoir détecter lorsque l'utilisateur clic sur un bouton mais sans relacher le bouton de la sourie, et effectuer un traitement jusqu'a ce qu'il relâche le bouton. C'est pour effectuer les fonctions 'Rembobiner' et 'avance rapide' pour un player audio.
    A part la solution de Medinoc avoir recours au subclassing, je ne vois pas autrement..
    Une solution toute simple serait de connaitre les coordonnées du bouton et capter les messages WM_LBUTTONDOWN et WM_LBUTTONUP dans la WindowProc de la fenêtre de dialogue..
    la solution du subclassing c'est de rediriger la WindowProc du bouton vers une autre WindowProc particulière ou on peut capter les messages souris

  15. #15
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Désolé je n'y arrive pas. J'ai passé une bonne partie de la nuit à essayer mais sans succès.

    Je ne comprend pas le fonctionnement.

    PS : je cherche aussi comment trier un Lisbox sur le clic d'un bouton, si vous avez des infos je suis preneur.

    Merci à tous.

  16. #16
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    Salut Yann39,

    Je t'ai mis en pièce jointe l'exemple modifié de CodeGuru :

    quand tu appuies sur le bouton gauche, il te le dit dans le titre de la dialogue
    de même quand tu le relaches : de plus, dans ce cas, il t'affiche la valeur d'une variable public de la boîte de dialogue (534)

    d'après ce que j'ai compris, c'est ce que tu voulais

    qu'en penses-tu

    Philippe
    Fichiers attachés Fichiers attachés

  17. #17
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    J'ai réussi à intégrer l'exemple que tu me propose dans mon application.


    Ainsi lorsque je clique sur le bonton "avancer" de mon player j'ai bien le message "Bouton gauche appuyé" qui s'affiche dans la barre de titre.

    Mais je n'ai pas accès aux fonctions ni aux attributs de ma classe CPlayerDlg !
    Je peut bien faire :
    pParent->SetWindowText("Bouton gauche appuyé");
    mais pas par exemple :
    pParent->MaVariable = true;
    ou :
    pParent->AvancerLecture();

    car MaVariable ou AvancerLecture() ne sont pas disponible.

    Que faire ?

    Il me semble avoir déjà eu plusieurs fois un message d'avertissement du genre "impossible de modifier truc car la classe CAudioDlg est en lecture seule" lorsque je tentais de faire je ne sais plus quoi.
    Ca peut venir de ça ?

    Merci, on va y arriver

  18. #18
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    mais pas par exemple :
    pParent->MaVariable = true;
    ou :
    pParent->AvancerLecture();
    je ne comprends pas, je le fais bien dans mon exemple :
    variableTest, j'y accède très bien puisque je l'affiche !!

    as-tu déclaré MaVariable comme je l'ai fait pour variableTest ?

    car MaVariable ou AvancerLecture() ne sont pas disponible.
    désolé, mais ça ne veux rien dire rigoureusement ...

    est-ce ça bloque à la compilation ? auquel cas il faut donner l'erreur complète (copie-colle la ligne complète de la fenètre Output)

    ou bien tu as une erreur à l'exécution, en Debug ? et là aussi, il faut me donner tous les détails de ce que Debug te dit

    Sur, on va y arriver

  19. #19
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Décembre 2006
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 255
    Par défaut
    Il suffit bien de déclarer cette variable dans le .h de CPlayerDlg pour pouvoir y accéder ?

    Je ne peut accéder à aucunes de mes fonctions ou attributs défnies dans le .h de ma classe CPlayerDlg !

    Je n'ai aucunes erreurs de compilation simplement lorsque je fait un Ctrl+space après la flèche -> afin de lister les fonctions disponibles, elles n'y apparaissent pas.

    Je ne comprend pas.



    HS : Concernant la compilation je compile toujours en debug.

    En release j'ai dû tout caster en CString pour éviter les erreurs du type :
    error C2664: 'CWnd::SetWindowTextW'*: impossible de convertir le paramètre 1 de 'const char [21]' en 'LPCTSTR'
    et par exemple pour un slider control il faut apparement faire :
    libAvancement.SetWindowTextW((CString)csAffPosSurDuree);
    au lieu de :
    libAvancement.SetWindowTextA(csAffPosSurDuree);

    C'est normal que l'on doivent modifier le code quand on passe de debug à release ?

    Et en release certaine fonctionnalités de mon application ne fonctionnent plus...

  20. #20
    Membre confirmé Avatar de Philippe320
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 179
    Par défaut
    oui, mais il faut déclarer la variable en zone public: (sinon, il va te jeter en compilation en disant qu'il ne peut pas accéder à une variable privée ou protégée)

    en ce qui concerne CTRL+SPACE, je n'utilise pas, mais bon, si les fonctions et variables sont déclarées en public, il devrait les lister
    sinon, tant pis, on s'en fout en fait, faut pas que tu considères ça comme une erreur, il faut juste les taper à la mimine ...
    ce qui compte, c'est que ça passe à la compilation !
    (la liste de CTRL+SPACE, c'est une aide de l'éditeur, ni plus ni moins)

    pour les cast à répétition, VS2005 est pénible (ou hyper rigoureux ),
    j'en ai eu 185 dans le projet que je viens de convertir de VC6 à VC2005 ...

    mais tu peux éviter tous ces warning en mettant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #pragma warning(disable:4244)
    (attention car certains peuvent révéler un vrai problème de conversion tout de même)


    pour moi, c'est la même chose en debug qu'en release

    et si des fonctionnalités ne fonctionnent plus en release, y'a vraiment un problème, mais qui me dépasse (faudrait faire un autre post avec le problème précis + code )

    Philippe

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

Discussions similaires

  1. Detection de la souris sur un controle
    Par LibidoPostToxico dans le forum VB.NET
    Réponses: 6
    Dernier message: 17/06/2010, 12h32
  2. Detection de la deconnexion de la souris sur ps2
    Par ichafik2000 dans le forum API, COM et SDKs
    Réponses: 0
    Dernier message: 31/01/2009, 14h54
  3. simuler un click souris sur un CButton pb
    Par Emyleet dans le forum MFC
    Réponses: 2
    Dernier message: 13/06/2008, 09h16
  4. Detection de click souris sur form - Besoin d'aide
    Par ggcourtois dans le forum Windows Forms
    Réponses: 11
    Dernier message: 22/03/2007, 14h39
  5. Réponses: 4
    Dernier message: 08/09/2006, 04h36

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