Voici un code de hook Clavier + Souris devellopé en vb.net 1.1 et le même en 2.0
Avant tte remarque du style "ouin ouin ... yen a deja plein"
le but de ce post n'est pas exculsivment de montrer comment on hook mais de mettre a jour et de m'aider à résoudre un soucis a savoir :
Le code .net 1.1 tourne avec VS 2003 fonctionnent bien actuellemnt (XP pro, avec VS 2003 + VS 2005 + framework 1.1 et framework 2.0 installer sur la meme machine), le bouton "Hook/UnHook" met en route une surveillance clavier souris et le timer dans el label indique depuis combien de temps le clavier et la souris n'ont pas été utiliser (il repars a zéro des qu'on y touche) => l'IdleTime en somme. Ceci avec une limite maximal reglable dans le module a la ligne suivante :
If ((nTickActuel - nTickIdle) / (1000 * 60)) >= 15 Then
ici la limite est donc de 15 minutes
Source / Exemple :
Imports System.Runtime.InteropServices
Imports System.Reflection
Module Hook
#Region "APIs"
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Integer) As Integer
Private Declare Function SetWindowsHookExClavier Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, ByVal lpfn As HookClavierDelegate, ByVal hmod As Integer, ByVal dwThreadId As Integer) As Integer
Private Declare Function SetWindowsHookExSouris Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, ByVal lpfn As HookSourisDelegate, ByVal hmod As Integer, ByVal dwThreadId As Integer) As Integer
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
Private Declare Function CallNextHookExClavier Lib "user32" Alias "CallNextHookEx" (ByVal hHook As Integer, ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As KBDLLHOOKSTRUCT) As Integer
Private Declare Function CallNextHookExSouris Lib "user32" Alias "CallNextHookEx" (ByVal hHook As Integer, ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As MSLLHOOKSTRUCT) As Integer
#End Region
#Region "Structures et Constantes"
Private Structure POINT
Private x As Integer
Private y As Integer
End Structure
Private Structure MSLLHOOKSTRUCT
Public pt As POINT
Public mouseData As Integer
Public flags As Integer
Public time As Integer
Public dwExtraInfo As Integer
End Structure
Private Structure KBDLLHOOKSTRUCT
Public vkCode As Integer
Public scanCode As Integer
Public flags As Integer
Public time As Integer
Public dwExtraInfo As Integer
End Structure
Private Const HC_ACTION As Integer = 0
Private Const WH_KEYBOARD_LL As Integer = 13
Private Const WH_MOUSE_LL As Integer = 14
#End Region
#Region "Delegate"
Private Delegate Function HookClavierDelegate(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
Private Delegate Function HookSourisDelegate(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As MSLLHOOKSTRUCT) As Integer
<MarshalAs(UnmanagedType.FunctionPtr)> Private dlgClavierCallBack As HookClavierDelegate
<MarshalAs(UnmanagedType.FunctionPtr)> Private dlgSourisCallBack As HookSourisDelegate
#End Region
Private hHookClavier As Integer
Private hHookSouris As Integer
Private WithEvents tmrSeconde As Timers.Timer
Private nTickIdle As Integer
Public Function Hook() As Boolean
Dim hInstance As Integer
dlgClavierCallBack = New HookClavierDelegate(AddressOf ClavierCallBack)
dlgSourisCallBack = New HookSourisDelegate(AddressOf SourisCallBack)
hInstance = Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32
hHookClavier = SetWindowsHookExClavier(WH_KEYBOARD_LL, dlgClavierCallBack, hInstance, 0)
hHookSouris = SetWindowsHookExSouris(WH_MOUSE_LL, dlgSourisCallBack, hInstance, 0)
If ((hHookClavier <> 0) AndAlso (hHookSouris <> 0)) Then
tmrSeconde = New Timers.Timer
tmrSeconde.AutoReset = True
tmrSeconde.Interval = 100
nTickIdle = Environment.TickCount
tmrSeconde.Start()
Return True
Else
Return False
End If
End Function
Public Sub UnHook()
If hHookClavier <> 0 Then
UnhookWindowsHookEx(hHookClavier)
End If
If hHookSouris <> 0 Then
UnhookWindowsHookEx(hHookSouris)
End If
tmrSeconde.Stop()
tmrSeconde.Close()
hHookClavier = 0
hHookSouris = 0
dlgClavierCallBack = Nothing
dlgSourisCallBack = Nothing
tmrSeconde = Nothing
End Sub
Private Sub tmrSeconde_Elapsed(ByVal sender As Object, ByVal e As Timers.ElapsedEventArgs) Handles tmrSeconde.Elapsed
Dim nTickActuel As Integer = Environment.TickCount
'Delai de l'Idle: 20 minute
Dim frm As Form1 = CType(Form1.ActiveForm, Form1)
frm.Affichage(nTickActuel - nTickIdle)
If ((nTickActuel - nTickIdle) / (1000 * 60)) >= 15 Then
'On concidère que l'Idle est suffisant pour declenché le processus
UnHook()
Stop
'EVENTS()
End If
End Sub
#Region "CallBack"
Private Function ClavierCallBack(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
If (Code = HC_ACTION) Then
nTickIdle = Environment.TickCount
End If
Return CallNextHookExClavier(hHookClavier, Code, wParam, lParam)
End Function
Private Function SourisCallBack(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As MSLLHOOKSTRUCT) As Integer
If (nCode = HC_ACTION) Then
nTickIdle = Environment.TickCount
End If
Return CallNextHookExSouris(hHookSouris, nCode, wParam, lParam)
End Function
#End Region
End Module
Conclusion :
Qu'est ce qui ne va pas ?
j'ai créé un nouveau projet sous VS2005 (.net 2.0) meme nom de form, de boutton, de label, de module
copier coller dans les procédures
précompilateur => 0 messages, warnings, erreurs
compilateur => 0 messages, warnings, erreurs
éxecution => 0 excpetions
travail demandé => pas fait du tout
localisation du pb :
[...]
Private hHookClavier As Integer
Private hHookSouris As Integer
[...]
hHookClavier = SetWindowsHookExClavier(WH_KEYBOARD_LL, dlgClavierCallBack, hInstance, 0)
hHookSouris = SetWindowsHookExSouris(WH_MOUSE_LL, dlgSourisCallBack, hInstance, 0)
[...]
quand le code marche "hHookClavier" et "hHookSouris" sont censé recevoir le numero du handle du hook (un identifiant système unique qui permet de savoir que ca a marcher en somme), la doc de "SetWindowsHookExA" indique :
Return Value
If the function succeeds, the return value is the handle to the hook procedure.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
autre passage de la doc MSDN :
Visual Basic: Applications should call err.LastDllError instead of GetLastError.
ici les 2 integer resultants sont NULL, donc il c'est produit une erreur durant l'appelle, au débugage j'ai donc rajouté 2 ligne :
hHookClavier = SetWindowsHookExClavier(WH_KEYBOARD_LL, dlgClavierCallBack, hInstance, 0)
Dim nBug1 As Integer = Err.LastDllError
hHookSouris = SetWindowsHookExSouris(WH_MOUSE_LL, dlgSourisCallBack, hInstance, 0)
Dim nBug2 As Integer = Err.LastDllError
et la "nBug1" et "nBug2" sont tout les 2 égale a 0 et quoi qu'il en soit Err n'est meme pas remplis qqsoti le champs
en somme : SetWindowsHookEx dit qu'il y a une erreur et en même temps le service d'erreur windows me dit qu'il n'y en a pas.
je suis donc actuellment assez embetté, je ne sais pas ocmment résoudre ce pb :
- Faut il changer la manière/Méthode/Syntaxe des délégué sous .net 2.0 pour le cas ici présent
- Le handle de l'instance est il tjs correct sous .Net 2.0
- Autre ...
enfin si qqun pouvais m'aider a résoudre ce pb ca m'aiderai bcp merci d'avance
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.