hook (global) sur le clavier - empêcher le traitement ultérieur

hook (global) sur le clavier - empêcher le traitement ultérieur - API Win32 - Programmation

Marsh Posté le 20-02-2010 à 17:39:57    

Bonjour,
 
J'apprécierais de l'aide sur le problème suivant.
 
Mon but final est que l'appui sur la touche F12 entraîne l'impression de la date (par SendKeys) dans l'application qui a le focus (que ce soit Outlook, Word, Excel, etc...). J'ai donc mis en place en VB.NET un "global keyboard hook" à l'échelle du système, qui fonctionne bien (code ci-dessous).
 
Mon seul souci est que je souhaiterais neutraliser toute interception ultérieure par le système du même F12. Par exemple, l'appui sur F12 sous Word imprime bien la date, mais lance en même temps la boîte de dialogue ("Enregistrer sous..." ), car F12 est la raccourci clavier naturel pour cette boîte de dialogue sous Word (hook local). La date s'imprime en fait au sein d'un champ de cette boîte de dialogue.
 
En d'autres termes, je souhaiterais améliorer le hook pour que l'appui sur F12 fasse ce que je souhaite (c'est déjà le cas), mais rien d'autre. C'est-à-dire faire en sorte que, hormis mon traitement, le système "oublie" que F12 a été pressé.
 
Je débute en VB.net : je compte sur votre indulgence.
 
Merci d'avance pour votre aide,
Cordialement,
 
Nicolas
 

Code :
  1. ' Option Strict On
  2. Option Explicit On
  3. ' inspired by:
  4. ' http://jo0ls-dotnet-stuff.blogspot [...] etect.html
  5. Imports System.Runtime.InteropServices
  6. Public Class Form1
  7.     Private Const WH_KEYBOARD_LL As Integer = 13
  8.     Private Const WM_KEYUP As Integer = &H101
  9.     Private Const WM_SYSKEYUP As Integer = &H105
  10.     Private proc As LowLevelKeyboardProcDelegate = AddressOf HookCallback
  11.     Private hookID As IntPtr
  12.     Private Delegate Function LowLevelKeyboardProcDelegate(ByVal nCode As Integer, ByVal wParam As IntPtr, _
  13.         ByVal lParam As IntPtr) As IntPtr
  14.     <DllImport("user32" )> _
  15.     Private Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As LowLevelKeyboardProcDelegate, _
  16.         ByVal hMod As IntPtr, ByVal dwThreadId As UInteger) As IntPtr
  17.     End Function
  18.     <DllImport("user32.dll" )> _
  19.     Private Shared Function UnhookWindowsHookEx(ByVal hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
  20.     End Function
  21.     <DllImport("user32.dll" )> _
  22.     Private Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, _
  23.         ByVal lParam As IntPtr) As IntPtr
  24.     End Function
  25.     <DllImport("kernel32.dll", CharSet:=CharSet.Unicode)> _
  26.     Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
  27.     End Function
  28.     Sub New()
  29.         InitializeComponent()
  30.         Text = "KeyboardPlus 1.01"
  31.         hookID = SetHook(proc)
  32.     End Sub
  33.     Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
  34.         UnhookWindowsHookEx(hookID)
  35.     End Sub
  36.     Private Function SetHook(ByVal proc As LowLevelKeyboardProcDelegate) As IntPtr
  37.         Using curProcess As Process = Process.GetCurrentProcess()
  38.             Using curModule As ProcessModule = curProcess.MainModule
  39.                 Return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0)
  40.             End Using
  41.         End Using
  42.     End Function
  43.     Private Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
  44.         ' "The WM_KEYUP message is posted to the window with the keyboard focus
  45.         ' when a nonsystem key is released. A nonsystem key is a key that is pressed when the ALT key is not pressed,
  46.         ' or a keyboard key that is pressed when a window has the keyboard focus."
  47.         If nCode >= 0 AndAlso (wParam.ToInt32 = WM_KEYUP OrElse wParam.ToInt32 = WM_SYSKEYUP) Then
  48.             Dim vkCode As Integer = Marshal.ReadInt32(lParam)
  49.             If vkCode = Keys.F12 Then
  50.                 Dim dateOfTheDay As Char() = DateAndTime.Now.ToString.ToCharArray
  51.                 If Console.CapsLock Then
  52.                     SendKeys.Send("{CAPSLOCK}" )
  53.                     For index As Integer = 0 To 9
  54.                         SendKeys.Send(dateOfTheDay(index))
  55.                     Next
  56.                     SendKeys.Send("{CAPSLOCK}" )
  57.                 Else
  58.                     For index As Integer = 0 To 9
  59.                         SendKeys.Send(dateOfTheDay(index))
  60.                     Next
  61.                 End If
  62.             End If
  63.         End If
  64.         Return CallNextHookEx(hookID, nCode, wParam, lParam)
  65.     End Function
  66. End Class

Reply

Marsh Posté le 20-02-2010 à 17:39:57   

Reply

Marsh Posté le 20-02-2010 à 22:53:47    

Rajoute la ligne suivante juste après la ligne 75 :

Code :
  1. Return 0


Message édité par Harkonnen le 20-02-2010 à 22:57:31

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 21-02-2010 à 21:49:37    

Merci de ton aide.
 
Malheureusement, cela ne fonctionne pas. :-(
Même le remplacement du "Return CallNextHookEx(hookID, nCode, wParam, lParam)" général par "Return 0" n'empêche pas l'interception de F12 par Word.
 
Après recherche plus avancée, j'ai découvert que les hooks spécifiques des threads passent avant les hooks globaux :
"For a specified hook type, thread hooks are called first, then global hooks."
(http://msdn.microsoft.com/en-us/li [...] 85%29.aspx)
 
Sauriez-vous comment passer devant ces hooks spécifiques aux threads ?
 
Merci d'avance,
 
Nicolas
 

Reply

Marsh Posté le 22-02-2010 à 10:27:12    

Au lieu de faire un hook clavier, tu peux tenter de faire un hook de lancement de programme qui va injecter un thread qui va mettre en place un hook clavier au sein même de l'application. (bonjour les efforts à faire...)
Cela dit je trouve pas terrible ta façon de faire les choses car tu prives l'utilisateur d'un raccourci clavier (dans ton exemple celui de "enregistrer sous" )!
Tu devrais plutôt essayer de chercher un autre raccourci clavier moins utiliser genre "CTRL + ²"


Message édité par breizhbugs le 22-02-2010 à 10:32:07
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed