Hook clavier

Résolu
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 - 21 oct. 2006 à 20:05
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 - 23 oct. 2006 à 18:01
Bonjour,

J'ai trouvé sur le site de microsoft un exemple qui permeté de mettre en place un hook sur la souris, j'ai essayé de le modifié pour faire un hook sur un clavier mais ça ne marche pas

voici l'erreur :

L'exception System.AccessViolationException n'a pas été gérée
  Message="Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée."
  Source="System.Windows.Forms"
  StackTrace:
       à System.Windows.Forms.SafeNativeMethods.MessageBox(HandleRef hWnd, String text, String caption, Int32 type)
       à System.Windows.Forms.MessageBox.ShowCore(IWin32Window owner, String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, Boolean showHelp)
       à System.Windows.Forms.MessageBox.Show(String text)
       à WindowsApplication1.Form1.KeyboardHookProc(Int32 nCode, IntPtr wParam, IntPtr lParam) dans C:\Documents and Settings\thom\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs:ligne 86
       à System.Windows.Forms.SafeNativeMethods.MessageBox(HandleRef hWnd, String text, String caption, Int32 type)
       à System.Windows.Forms.MessageBox.ShowCore(IWin32Window owner, String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, Boolean showHelp)
       à System.Windows.Forms.MessageBox.Show(String text)
       à WindowsApplication1.Form1.KeyboardHookProc(Int32 nCode, IntPtr wParam, IntPtr lParam) dans C:\Documents and Settings\thom\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs:ligne 86
       à System.Windows.Forms.UnsafeNativeMethods.PeekMessage(MSG& msg, HandleRef hwnd, Int32 msgMin, Int32 msgMax, Int32 remove)
       à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       à System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       à System.Windows.Forms.Application.Run(Form mainForm)
       à WindowsApplication1.Program.Main() dans C:\Documents and Settings\thom\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Program.cs:ligne 17
       à System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       à System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       à System.Threading.ThreadHelper.ThreadStart()
<hr />

Voici le code source ( en csharp ) :

http://phpdebutant.org/wall4323.php

Merci de votre aide

17 réponses

Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
22 oct. 2006 à 20:01
Parce que tu ne veux pas lire les liens que je te donne.

Quelque chose comme ça :

try
{
   if ( ( int )wParam == 0x0101 /* WM_KEYUP */ )
      MessageBox.Show( ( ( Keys )p->Key ).ToString( ) );


 // ..
}
catch // Au cas ou tu as une exeption dans ta methode callback.
{
   return CallNextHookEx( hook, code, wParam, lParam );
}
3
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
21 oct. 2006 à 22:09
Salut..


Pourquoi cette structure ??







[StructLayout(LayoutKind.Sequential)] 
public class KeyboardHookStruct 

 public uint code; 
 public uint wParam; 
 public uint lParam; 
}

Si tu souhaites "espionner" le clavier hors de ton application, regardes plutôt comment implementer un hook global : WH_KEYBOARD_LL Hook



http://www.codeproject.com/csharp/globalhook.asp
0
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
21 oct. 2006 à 22:14
Il faut une DLL externe c'est ça ??
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
22 oct. 2006 à 00:21
Non entièrement en C#.. tu peux t'inspirer du hook pour la souris que j'ai posté >ici< Il y'a deux ou trois petites choses à modifier, MSLLHOOKSTRUCT qu'il faut remplacer par KBDLLHOOKSTRUCT et le type de hook WH_MOUSE_LL à remplacé par WH_KEYBOARD_LL.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
22 oct. 2006 à 11:44
J'ai mis WH_KEYBOARD_LL à 13  j'ai refactorisé le code pour changer KBDLLHOOKSTRUCT
Seulement je ne sais pas quoi mettre pour que lorsqu'une touche est enfoncé une messageBox nous informe quel touche on vient de presser

voici le code :


<hr />



#region



Win32[


StructLayout
(

LayoutKind
.Sequential)]


private



struct



KBDLLHOOKSTRUCT

{







public



int
X;


public



int
Y;


public



int
Data;


public



int
Flags;


public



int
Time;


public



UIntPtr
Extra;}

[


DllImport
(

"user32.dll"
, SetLastError =

true
),

SuppressUnmanagedCodeSecurity
]


private



static



extern



IntPtr
SetWindowsHookEx(

int
hook,

HookProc
callback,

IntPtr
module,

uint
threadID);[


DllImport
(

"user32.dll"
, SetLastError =

true
),

SuppressUnmanagedCodeSecurity
]


private



static



extern



bool
UnhookWindowsHookEx(

IntPtr
hHook);[


DllImport
(

"user32.dll"
),

SuppressUnmanagedCodeSecurity
]


private



static



extern



IntPtr
CallNextHookEx(

IntPtr
hHook,

int
code,

UIntPtr
wParam,

IntPtr
lParam);


private



delegate



IntPtr



HookProc
(

int
code,

UIntPtr
wParam,

IntPtr
lParam);


private



const



int
WH_KEYBOARD_LL = 13;


private



const



int
HC_ACTION = 0;


#endregion



Win32


private



IntPtr
hHook =

IntPtr
.Zero;


private



HookProc
hookProc =

null
;


public
Form1(){

InitializeComponent();

}

 


private



void
Form1_Load(

object
sender,

EventArgs
e){


//base.OnLoad(e);

hookProc =




new



HookProc
(LowLevelMouseProc);hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc,


Marshal
.GetHINSTANCE(

this
.GetType().Module), 0);


if
(hHook ==

IntPtr
.Zero)

// Le hook ne s'installe pas en mode DEBUG.






MessageBox
.Show(

"Impossible d'installer le hook."
,

"Erreur"
);}


protected



override



void
OnFormClosed(

FormClosedEventArgs
e){


base
.OnFormClosed(e);


if
(hHook !=

IntPtr
.Zero){


if
(!UnhookWindowsHookEx(hHook))


MessageBox
.Show(

"Impossible de désinstaller le hook."
,

"Erreur"
);hHook =


IntPtr
.Zero;hookProc =


null
;}

}


private



IntPtr
LowLevelMouseProc(

int
code,

UIntPtr
wParam,

IntPtr
lParam){


if
(code == HC_ACTION){


unsafe

{







KBDLLHOOKSTRUCT
* p = (

KBDLLHOOKSTRUCT
*)lParam;}

}


return
CallNextHookEx(hHook, code, wParam, lParam);}
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
22 oct. 2006 à 19:28
Attention tu dois redéfinir la structure KBDLLHOOKSTRUCT elle est différente de MSLLHOOKSTRUCT :

true http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookstructures/kbdllhookstruct.asp?frame=true

[ StructLayout( LayoutKind.Sequential ) ]
protected struct KBDLLHOOKSTRUCT
{
 public int Key;
 public int Code;
 public int Flags;
 public int Time;
 public UIntPtr Extra;
}

Si tu n'as pas l'habitude du code unsafe tu peux passer Marshal.PtrToStructure comme tu faisais dans ton premier exemple.

De mémoire comme ça je pense qu'il n y a pas d'autres différences entre un hook clavier et un hook souris mais comme ça fait longtemps que j'ai pas codé de hook pour le clavier je te conseille quand même de relire la MSDN ici :



=true http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/abouthooks.asp?frame=true



Car si jamais ton hook est mal codé, c'est tout le système qui va être ralentit.
0
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
22 oct. 2006 à 19:34
Pour la structure c'est changé mais comment je peux faire pour afficher dans une MessagBox la touche qui vient d'etre frapé ?
0
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
22 oct. 2006 à 19:38
enfete j'ai trouvé :


<hr />

unsafe




{







KBDLLHOOKSTRUCT
* p = (

KBDLLHOOKSTRUCT
*)lParam;


MessageBox
.Show(p->Key.ToString());}

<hr />
mais le prob c'est que la messagBox aparait deux fois
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
22 oct. 2006 à 19:46
Une fois pour la touche pressée et une fois pour la touche relachée je pense ^^

wParam contient le message  WM_KEYDOWN ou WM_KEYUP etc.. et lParam contient la structure, enfin tout ça c'est expliqué dans les liens que je t'ai donné.

Tu peux faire un cast comme çà :

( Keys )p->Key;
0
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
22 oct. 2006 à 19:49
MessageBox



.Show(

Convert
.ToString((

Keys
)p->Key));

ça marche toujours pas
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
22 oct. 2006 à 19:51
Qu'est ce qui ne marche pas.. tu obtiens le code de la touche ou pas ??
0
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
22 oct. 2006 à 19:52
Oui mais deux fois
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
22 oct. 2006 à 19:54
Bha je viens de t'expliquer pourquoi.. il faut gérer le message WM_KEYDOWN et WM_KEYUP contenu dans wParam.
0
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
22 oct. 2006 à 19:57
J'ai aucune idée de comment il faut faire desolé
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
22 oct. 2006 à 20:07
Par contre c'est peut être pas ce qu'il y a de mieux d'afficher une MessageBox dans un hook sans avoir passé avant le hook avec CallNextHookEx.
0
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
22 oct. 2006 à 20:09
Merci je teste demin.
Desolé mais mon niveau d'anglais n'est pas très élevé
0
iow4 Messages postés 302 Date d'inscription samedi 22 octobre 2005 Statut Membre Dernière intervention 2 novembre 2008 4
23 oct. 2006 à 18:01
Ca marche niquel merci
0
Rejoignez-nous