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

VB.NET Discussion :

hook (global) sur le clavier - empêcher le traitement ultérieur (local) de la touche


Sujet :

VB.NET

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    429
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 429
    Points : 475
    Points
    475
    Par défaut hook (global) sur le clavier - empêcher le traitement ultérieur (local) de la touche
    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 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 : 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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    ' Option Strict On
    Option Explicit On
     
    ' inspired by:
    ' http://jo0ls-dotnet-stuff.blogspot.com/2008/12/vbnet-global-keyboard-hook-to-detect.html
     
    Imports System.Runtime.InteropServices
     
    Public Class Form1
     
        Private Const WH_KEYBOARD_LL As Integer = 13
        Private Const WM_KEYUP As Integer = &H101
        Private Const WM_SYSKEYUP As Integer = &H105
        Private proc As LowLevelKeyboardProcDelegate = AddressOf HookCallback
        Private hookID As IntPtr
     
        Private Delegate Function LowLevelKeyboardProcDelegate(ByVal nCode As Integer, ByVal wParam As IntPtr, _
            ByVal lParam As IntPtr) As IntPtr
     
        <DllImport("user32")> _
        Private Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As LowLevelKeyboardProcDelegate, _
            ByVal hMod As IntPtr, ByVal dwThreadId As UInteger) As IntPtr
        End Function
     
        <DllImport("user32.dll")> _
        Private Shared Function UnhookWindowsHookEx(ByVal hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
     
        <DllImport("user32.dll")> _
        Private Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, _
            ByVal lParam As IntPtr) As IntPtr
        End Function
     
        <DllImport("kernel32.dll", CharSet:=CharSet.Unicode)> _
        Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
        End Function
     
        Sub New()
            InitializeComponent()
            Text = "KeyboardPlus 1.01"
            hookID = SetHook(proc)
        End Sub
     
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
            UnhookWindowsHookEx(hookID)
        End Sub
     
        Private Function SetHook(ByVal proc As LowLevelKeyboardProcDelegate) As IntPtr
            Using curProcess As Process = Process.GetCurrentProcess()
                Using curModule As ProcessModule = curProcess.MainModule
                    Return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0)
                End Using
            End Using
        End Function
     
        Private Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
            ' "The WM_KEYUP message is posted to the window with the keyboard focus
            ' when a nonsystem key is released. A nonsystem key is a key that is pressed when the ALT key is not pressed,
            ' or a keyboard key that is pressed when a window has the keyboard focus." 
            If nCode >= 0 AndAlso (wParam.ToInt32 = WM_KEYUP OrElse wParam.ToInt32 = WM_SYSKEYUP) Then
                Dim vkCode As Integer = Marshal.ReadInt32(lParam)
                If vkCode = Keys.F12 Then
                    Dim dateOfTheDay As Char() = DateAndTime.Now.ToString.ToCharArray
                    If Console.CapsLock Then
                        SendKeys.Send("{CAPSLOCK}")
                        For index As Integer = 0 To 9
                            SendKeys.Send(dateOfTheDay(index))
                        Next
                        SendKeys.Send("{CAPSLOCK}")
                    Else
                        For index As Integer = 0 To 9
                            SendKeys.Send(dateOfTheDay(index))
                        Next
                    End If
                End If
            End If
            Return CallNextHookEx(hookID, nCode, wParam, lParam)
        End Function
     
    End Class

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    429
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 429
    Points : 475
    Points
    475
    Par défaut
    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/libr...8VS.85%29.aspx)
    Sauriez-vous comment passer devant ces hooks spécifiques aux threads ?

    Merci d'avance,

    Nicolas

  3. #3
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 179
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 179
    Points : 1 776
    Points
    1 776
    Par défaut
    Bonjour.

    Supprime le CallNextHookEx.

    Mais bon, comme je l'ai écris dans un article sur les hooks souris, c'est pas ce qu'il y a de mieux...

    Nota : c'est pas super propre de déclarer des API dans une form, j'espére que c'est juste pour illustrer le probléme...

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    429
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 429
    Points : 475
    Points
    475
    Par défaut
    Merci pour ta réponse.

    J'ai supprimé le CallNextHookEx, mais le problème subsiste (le raccourci clavier de Word intercepte avant mon hook global).

    C'est probablement dû au phénomène décrit dans mon message précédent ci-dessus (interception par les threads avant les hooks globaux).

    Je reste preneur de toute idée.

    Merci encore,

    Nicolas

  5. #5
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 179
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 179
    Points : 1 776
    Points
    1 776
    Par défaut
    Bonjour.

    Si les applis de type word posent des hooks globaux, ça n'est finalement qu'une question de chaînage.

    Et là, tu ne pourras pas faire grand chose dans le cas où le hook de l'appli est posé aprés le tiens...

    Désolé, mais ça me semble insoluble par ce biais.

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

Discussions similaires

  1. Lire une fonction numérique sur le clavier
    Par ladognon dans le forum Langage
    Réponses: 3
    Dernier message: 08/04/2006, 19h07
  2. Réponses: 7
    Dernier message: 16/03/2006, 20h54
  3. Réponses: 15
    Dernier message: 23/02/2006, 15h53
  4. [VB.NET] Var globales sur plusieurs projets d'une même solut
    Par boulete dans le forum Windows Forms
    Réponses: 8
    Dernier message: 16/02/2006, 14h04
  5. Réponses: 2
    Dernier message: 17/05/2005, 12h26

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