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 :

[Win32] Récupérer un appui touche clavier


Sujet :

MFC

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2003
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 28
    Points : 23
    Points
    23
    Par défaut [Win32] Récupérer un appui touche clavier
    Bonjour !

    Je bosse sous VC++6.0 avec Windows XP et en utilisant du WIN32 (et pas de MFC).

    Dans mon appli je créé une fenetre avec un DialogBox(...) standard. Dans la callback de ce DialogBox je voudrais intercepter un appui clavier pour detecter par exemple un appui sur la touche 'L' pour pouvoir faire une action dessus.

    Sauf que malgré les WM_KEYDOWN et autre WM_CHAR que je place dans la callback, je n'arrive pas a le faire fonctionner et je ne rentre jamais dans mon case WM_KEYDOWN.

    Je pense qu'il pourrait s'agir d'un probleme de focus clavier mais je ne vois pas comment le resoudre.

    Merci d'avance pour votre aide

  2. #2
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    tu voudrais intercepter un appui sur une touche qd tu es sur la dialogBox ou bien sur un des controles dans la dialogbox (comme un edit par exemple) ?

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2003
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 28
    Points : 23
    Points
    23
    Par défaut
    salut !

    je veux intercepter une touche quand je suis sur la dialog box et non pas sur un edit control.

    Mon but etant de faire en sorte que des que l'itulisateur tape sur une touche genre la touche 'k' on lance """une action secrete"""


  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    et je suppose que tu as d'autres controles dans ta dialogue box, sinon, le wm_char ou keydown fonctionne.

  5. #5
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    ce que je te propose, c'est soit de faire un sous-classement du controle qui a le focus pour intercepter la touche secrete (fastidieux)
    soit de faire un hook local pour intercepter toutes les touches claviers et traiter la touche secrete (mieux ), voir setwindowshookex

  6. #6
    Membre à l'essai
    Inscrit en
    Mai 2003
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 28
    Points : 23
    Points
    23
    Par défaut
    alors pour ce qui est des autres controles je n'ai que des statics et un button box. Mais meme avec ca si je fais un SetFocus() dans mon WM_INITDIALOG et que ensuite je fais des case WM_KEYDOWN, je ne passe pas dedans

    Pour ce qui est de faire des hook je connais pas trop mais je comprends pas ce que tu dis pour le "sous-classement du controle qui a le focus" ???

    Pour info je me suis depatouille autrement :
    Je fais un edit box invisible et je lui donne le focus. Apres j'intercepte tout e qui passe dans mon WM_COMMAND et qui concerne mon edit box et je fais un GetDlgItemText() dessus. Puis des que j'ai la bonne chaine (on passe au string secret maintenant ) je lance mon action "spéciale"

    Ceci etant je suis preneur de ta methode avec hook tout de meme (si tu as la patience de l'ecrire )

  7. #7
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    150
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 150
    Points : 180
    Points
    180
    Par défaut
    hehe on connais maintenant la touche secrete de ton appli ! c'est "e"
    Elle n'est plus secrete alors.

  8. #8
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    ahlala ... moi qui croyait que c'était 'k' la touche secrete .

    Voici donc pour l'exemple, le hook local au thread (rappel, pour un hook global, il faut une dll).

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #include <windows.h>
    #include "resource.h"
     
    HHOOK hookClavier;
     
    LRESULT CALLBACK fonctionIntercepteClavier (int nCode, WPARAM wParam, LPARAM lParam) 
    {
    	if(nCode >= 0) 
    	{
    		if (wParam == 75) // 75 pour K
    		{
    			// action à effectuer
    			// return 1 si on veut empecher le traitement de K
    		}
    	}
    	return CallNextHookEx(hookClavier, nCode, wParam, lParam);
    }
     
    BOOL CALLBACK dialogProc(HWND handleDialog, UINT mssg, WPARAM wParam, LPARAM lParam)
    {
    	switch(mssg)
    	{
    		case WM_INITDIALOG:
    			hookClavier  = SetWindowsHookEx(WH_KEYBOARD, fonctionIntercepteClavier, NULL, GetCurrentThreadId());
    			if (!hookClavier)
    				MessageBox(0,"erreur de hook","",0x10);
    			return 1;
    		case WM_COMMAND:
    			switch(wParam)
    			{
    				case IDOK:
    					MessageBox(0,"Boutton OK","",0x10);
    					return 1;
    				case IDCANCEL:
    					SendMessage(handleDialog,WM_QUIT,wParam,lParam);
    					return 1;
    			}
    			break;
    		case WM_CLOSE:
    		case WM_QUIT:
    			UnhookWindowsHookEx(hookClavier);
    			MessageBox(0,"Fin","",0x10);
    			PostQuitMessage(0);
    	}
    	return 0;
    }
     
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	DialogBoxParam(hInstance, (LPCTSTR)IDD_DIALOG1, 0, dialogProc, 0);
    	return 1;
    }
    Sachant que j'ai une dialogBox (d'identifiant IDD_DIALOG1), un bouton OK et un bouton CANCEL.

    Note : Ici, le k est intercepté meme dans tous les cas (meme dans un autre composant), donc si on le veut pas, il faut faire un cas spécial bien sur.

  9. #9
    Membre à l'essai
    Inscrit en
    Mai 2003
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 28
    Points : 23
    Points
    23
    Par défaut
    ok super merci a tous !

    Effectivement avec le Hook ca rend quand meme plus propre

    Je passe en résolu

    PS: et je change ma lettre secrete, c'est pas que j'ai pas confiance mais hein !!

  10. #10
    Nouveau membre du Club
    Inscrit en
    Avril 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 53
    Points : 33
    Points
    33
    Par défaut
    Bonjour,

    Je me suis inspiré de ce code et l'ai recopié. Seulement, voilà, je suis en win32 et essaies díntercepter non plus le caractère 'K' mais le caratère ".
    J'ai donc considéré wparam comme entier codé en ASCII (en raison du chiffre 74 associé au K précédent). Mais voilà, pas moyen de líntercepter le guillemet!

    Je me suis donc remis dans le cas du K majuscule et cela ne fonctionne que si j'autorise le MessageBox juste devant a etre compilé.

    Allant un peu plus loin, je n'ai rèussi à utiliser le code précédent que dans le cas de lettres majuscules (codes ASCII allant de 65 à 90)!Encore plus bizarre, quelquesoit la lettre majuscule que j'intercepte, meme si dans mon PostMessage je renvois k majuscule dans tous les cas. Dans ma EditBox, apparait la lettre minuscule de la lettre interceptée!
    En gros, 'A' intercepte renvoie 'a' meme si je demande 'k'!!

    Kézako?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    LRESULT CALLBACK fonctionIntercepteClavier (int nCode, WPARAM wParam, LPARAM lParam) 
    {
        if(nCode >= 0) 
        {
            if (wParam == 34) // 34 is the ASCII code for quote symbol "
            {
                //MessageBox(GetActiveWindow(),"K","K Touch",MB_OK);
                PostMessage(GetActiveWindow(),WM_CHAR,'k',0);
                // action à effectuer
                // return 1 si on veut empecher le traitement de K
            }
        }
        return CallNextHookEx(hookClavier, nCode, wParam, lParam);
    }

  11. #11
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    moi j'ai rien compris ...

    Les problèmes un par un

  12. #12
    Nouveau membre du Club
    Inscrit en
    Avril 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 53
    Points : 33
    Points
    33
    Par défaut
    Désolé...

    Problème1: Après avoir recopié le code ci-dessus, j'aij uste rajouté la fonction "PostMessage". Mon programme ne semblait alors pas intercepté le caractère K. J'ai donc rajouté une commande "MessageBox" afin de le vérifier.
    Alors, la messageBox apparait et le K est transformé en k.
    Conclusion: Sans la commande Messagebox précédant la commande PostMessage, K nést pas transformé en k.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    LRESULT CALLBACK fonctionIntercepteClavier (int nCode, WPARAM wParam, LPARAM lParam) 
    {
        if(nCode >= 0) 
        {
            if (wParam == 75) // 75 is the ASCII code for quote symbol "
            {
                MessageBox(GetActiveWindow(),"K","K Touch",MB_OK);
                PostMessage(GetActiveWindow(),WM_CHAR,'k',0);
                // action à effectuer
                // return 1 si on veut empecher le traitement de K
            }
        }
        return CallNextHookEx(hookClavier, nCode, wParam, lParam);
    }
    Problème2: "Essayons díntercepter les guillemets"
    J'ai donc remplacé par .
    Alors rien ne se passe: pas de messageBox et pas de k apparaissant dans la boite de dialogue.
    En essayant un peu plus, je me suis rendu compte que seuls les codes ASCII de 60 à 90 étaient captés par la condition sur wParam.

  13. #13
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    Citation Envoyé par Mac Twist
    Conclusion: Sans la commande Messagebox précédant la commande PostMessage, K nést pas transformé en k.
    Moi je dirais plutot : Conclusion : après le messagebox, GetActiveWindow donne le bon handle ... essaye plutot avec le handle de l'edit dans le postmessage

  14. #14
    Nouveau membre du Club
    Inscrit en
    Avril 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 53
    Points : 33
    Points
    33
    Par défaut
    Quelle fonction me permettrait d'avoir le handle de mon Edit?
    Merci.

  15. #15
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    par ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    hEdit = GetDlgItem(handleDialog, IDC_EDIT1);

  16. #16
    Nouveau membre du Club
    Inscrit en
    Avril 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 53
    Points : 33
    Points
    33
    Par défaut
    OK
    Maintenant, ca fonctionne sans le MessageBox compilé.
    Mais je suis toujours confronté au problème 2, soit seul un if(wparam=
    n) où n va de 65 à 90 (lettres de majuscules) permet d'entrer dans la condition.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        HWND hEdit;
        if(nCode >= 0) 
        {
            if (wParam == 75) // 34 is the ASCII code for quote symbol "
            {
                hEdit = GetDlgItem(GetActiveWindow(), IDC_EDIT_PREFIX);
                //MessageBox(GetActiveWindow(),"K","K Touch",MB_OK);
                PostMessage(hEdit,WM_CHAR,'k',0);
            }
        }
        return CallNextHookEx(hookClavier, nCode, wParam, lParam);

  17. #17
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    essaie

  18. #18
    Nouveau membre du Club
    Inscrit en
    Avril 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 53
    Points : 33
    Points
    33
    Par défaut
    Citation Envoyé par nico-pyright(c)
    essaie
    Bon ok les chiffres (ASCII de 47->58)marchent aussi...

    Mais essaies, 34 pour les guillemets ou meme 97 pour a...

  19. #19
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    la boite de dialogue opère à une translation pour ce genre de caractères.

    Je te propose une autre solution, qui est le sous-classement de l'edit box
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    WNDPROC ancienneEditProc;
     
    BOOL CALLBACK editProc(HWND hwnd, UINT mssg, WPARAM wParam, LPARAM lParam)
    {
        switch(mssg)
        {
            case WM_CHAR:
                {
                    if (wParam == 34)
                    {
                        MessageBox(NULL, "appui sur \"", "", 0);
                        return 0; // si on veut pas afficher le "
                    }
                }
        }
        return CallWindowProc(ancienneEditProc, hwnd, mssg, wParam, lParam);
    }
     
    BOOL CALLBACK dialogProc(HWND handleDialog, UINT mssg, WPARAM wParam, LPARAM lParam)
    {
        static HWND hedit;
        switch(mssg)
        {
            case WM_INITDIALOG:
                hedit = GetDlgItem(handleDialog, IDC_EDIT1);
                ancienneEditProc = (WNDPROC) SetWindowLong(hedit,GWL_WNDPROC,(long)editProc);
                return 1;
            case WM_COMMAND:
                switch(wParam)
                {
                    case IDOK:
                        MessageBox(0,"Boutton OK","",0x10);
                        return 1;
                    case IDCANCEL:
                        SendMessage(handleDialog,WM_QUIT,wParam,lParam);
                        return 1;
                }
                break;
            case WM_CLOSE:
            case WM_QUIT:
                PostQuitMessage(0);
        }
        return 0;
    }
     
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        DialogBoxParam(hInstance, (LPCTSTR)IDD_DIALOG1, 0, dialogProc, 0);
        return 1;
    }

  20. #20
    Nouveau membre du Club
    Inscrit en
    Avril 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 53
    Points : 33
    Points
    33
    Par défaut
    Merci. cette solution marche.
    ...Moins esthétique...mais elle marche

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 16/01/2009, 00h50
  2. envoyer la saisie après l'appui sur une touche clavier
    Par Jahjouh dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 13/06/2008, 10h20
  3. detecter le double "appuie" d'une touche clavier
    Par jadey dans le forum Flash
    Réponses: 4
    Dernier message: 25/03/2007, 01h43
  4. Réponses: 2
    Dernier message: 19/06/2005, 10h37
  5. Simuler un appui de touche clavier
    Par Floo dans le forum Assembleur
    Réponses: 5
    Dernier message: 03/12/2004, 17h04

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