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

Delphi Discussion :

Utilisation de keyhook


Sujet :

Delphi

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 189
    Par défaut Utilisation de keyhook
    Bonjour, j'aimerai savoir si quelqu'un ici sait comment fonctionnent les keyboard hooks.

    Je veux pouvoir capter la préssion d'une touche afin d'y assigner une action à faire.

    je pourai utiliser getasynckeystate mais je dois le faire avec des keyhooks .

    Donc quelqu'un saurai clairement m'éxpliquer le fonctionnement de ces hooks clavier ?

    Merci d'avance, car je sature en voyant des keyloggers avec trop de choses dont je n'ai pas besoin et qui empeche de comprendre son fonctionnement.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Par défaut
    Pour intercepter les messages "clavier" il faut:
    1) appeler SetWindowsHookEx de l'api Win32 avec le parametre WH_KEYBOARD.
    2)Définir une procedure de callback au sein de laquelle tu testes les touches et effectues le traitement spécifique.
    3)Puis libérer le hook avec UnhookWindowsHookEx();

    Consultes l'aide Win32, ce n'est pas très compliqué à mettre en place.

  3. #3
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Euh, si c'est pour VK_RMENU, tu seras déçu, le hook, je ne suis pas persuadé qu'il l'a renvoie puisque :

    The KeyboardProc hook procedure is an application-defined or library-defined callback function the system calls whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.
    tient, j'ai pondu ça, alors normalement un Hook faut le faire dans une DLL car sinon ça détourne les messages clavier de l'Application (en gros ça fout le bordel), ... tu vois faut juste l'encapsuler, c'est ultra facile, et tu fais un message perso WM_USER + 100, tu te transfère WPARAM et LPARAM dans ce message (faut fournir son handle à la DLL pour quelle sache ou l'envoyer)

    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
    var
      HookKeyboardHandle: HHook = 0;
     
    function HookKeyboardProc(Code: Integer; Msg: WPARAM; MouseHook: LPARAM): LRESULT; stdcall;
    begin
      FrmTestDivers.MemoHook.Text := FrmTestDivers.MemoHook.Text + IntToStr(Msg);
    end;
     
    procedure TFrmTestDivers.BtnHookStartClick(Sender: TObject);
    begin
      HookKeyboardHandle := SetWindowsHookEx(WH_KEYBOARD, HookKeyboardProc, HInstance, 0);
    end;
     
    procedure TFrmTestDivers.BtnHookStopClick(Sender: TObject);
    begin
      if HookKeyboardHandle <> 0 then
        UnhookWindowsHookEx(HookKeyboardHandle);
      HookKeyboardHandle := 0;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Par défaut
    Un second exemple

    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
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
     
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormKeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
      KeybdHook: HHook;
     
    implementation
     
    {$R *.DFM}
    function KeyboardProc(code: Integer; wParam: Word; lParam: LongInt):LResult;Stdcall;
    begin
      if wParam = VK_RETURN then Form1.Color := clYellow;
      Result := 1;   // Tester Result := 0;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      KeybdHook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardProc, HInstance, 0);
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      UnhookWindowsHookEx(KeybdHook);
    end;
     
    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
      if Key = VK_RETURN then ShowMessage('OnKeyDown');
    end;
     
    end.
    Dans la fonction KeyboardProc, mettre Result :=0 pour propager le message.
    -> FormKeyDown s'execute.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 189
    Par défaut
    Merci pour vos réponses !!
    Je retiens particulierement celle de notre ami Fabrice.
    Cependant il y a quelque chose que je ne comprends pas :

    Mettre result à 0 ne fait pas se propager le méssage.
    et donc formkeydown ne s'éxécute pas, mais en meme temps je ne vois pas d'appel de procédure.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Par défaut
    C'est le contraire.

    Si tu mets Result à 0, le message est propagé, c'est à dire que la procédure de fenêtre traitera le message clavier.
    FormKeyDown est là pour illustrer le principe.

    Avec Result <> 0, on dit à Windows de ne pas envoyer le message dans la file de message associée à la fenêtre.

    En fait Windows gere tous les evenements du systeme. Quand tu appuyes sur une touche du clavier, windows va identifier la fenetre concernée et envoyer un message clavier dans sa file de message. Ensuite une procedure de fenetre boucle en permanence en lisant la file de message puis dispatche les messages.
    Le hook intercepte le message destiné à la fenetre.dans la procedure de hook tu as l'opportuné via la valeur de retour d'indiquer à windows si le message doit etre posté dans la file de message de la fenetre cible ou bien s'il ne doit pas etre posté.

    Cet exemple de code illustre ce principe.

    Voila.

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Par défaut
    Penses au tag

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 189
    Par défaut
    Citation Envoyé par Fabrice ROUXEL 1
    Penses au tag
    Merci beaucoup !!!
    Ton votre m'a été trés précieuse !

    Edit: petite question encore, pourquoi si je met

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function KeyboardProc(code: Integer; wParam: Word; lParam: LongInt):LResult;StdCall;
    begin
      if wParam = VK_RMENU
      Then   keybd_event(VK_SPACE,0,0,0); //Préssion
      keybd_event(VK_SPACE,0,KEYEVENTF_KEYUP,0); //Relachement
     
      result := 1;
    end;
    l'envoi de touche ne marche pas ? :s

  9. #9
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Faut lire ce que l'on répond !

    Citation Envoyé par ShaiLeTroll
    Euh, si c'est pour VK_RMENU, tu seras déçu, le hook, je ne suis pas persuadé qu'il l'a renvoie puisque :

    Citation:
    The KeyboardProc hook procedure is an application-defined or library-defined callback function the system calls whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.
    Toujours le même problème VK_RMENU est une constante uniquement pour GetASyncKeyState et donc les Messages WM_KEY* ne l'intercepte que en 17+18 (ALT + CTRL), ... et les Hooks c'est juste des "Sniffers bas niveaux" des messages, pour le Clavier c'est WM_KEY*
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 189
    Par défaut
    Citation Envoyé par ShaiLeTroll
    Faut lire ce que l'on répond !



    Toujours le même problème VK_RMENU est une constante uniquement pour GetASyncKeyState et donc les Messages WM_KEY* ne l'intercepte que en 17+18 (ALT + CTRL), ... et les Hooks c'est juste des "Sniffers bas niveaux" des messages, pour le Clavier c'est WM_KEY*
    Oops, dans mon méssage j'ai écrit RMENU, hors c'est pareil avec toutes les vk :s, oublié de le préciser

    WM_Key, euh ok, je vais éssayer de voir comment cela fonctionne.

  11. #11
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Je crois que tu n'as toujours pas compris en fait

    WM_KEYUP or WM_KEYDOWN
    tu les as dans Events Delphi, dans les Hook, dans les PeekMessage ... ça fourni 17 (VK_CONTROL ) +18 (VK_MENU ) pour un ALT GR

    VK_RMENU est une constante SPECIALE uniquement disponible pour GetASyncKeyState

    Donc, si tu veux "capturer" les ALT GR sans passer par GetASyncKeyState, tu dois gérer la présence successive de 17 +18 ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 189
    Par défaut
    Citation Envoyé par ShaiLeTroll
    Je crois que tu n'as toujours pas compris en fait

    WM_KEYUP or WM_KEYDOWN
    tu les as dans Events Delphi, dans les Hook, dans les PeekMessage ... ça fourni 17 (VK_CONTROL ) +18 (VK_MENU ) pour un ALT GR

    VK_RMENU est une constante SPECIALE uniquement disponible pour GetASyncKeyState
    Ok trés bien !
    En effet, j'avais cru que WM_ remplacait VK_...

    Donc WM_ sert à indiquer l'état de la touche !
    C'est trés clair ! et quand à altgr, je voulais déjâ voir comment sa fonctionner avec n'importe quelle touche.

    Sa réponds trés bien à mes questions !!
    Merci beaucoup !!

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

Discussions similaires

  1. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 15h57
  2. Réponses: 4
    Dernier message: 05/06/2002, 14h35
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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