Clavier globaux crochet avec WH_KEYBOARD_LL et keybd_event (windows)

Je suis en train d'écrire un simple clavier crochet programme de rediriger certaines touches. Par exemple, lorsque le programme est exécuté, j'appuie sur " a "sur le clavier, le programme peut le désactiver et de simuler un "b", cliquez sur. Je n'ai pas besoin d'un graphique de l'interface utilisateur, juste une console est assez (le garder en cours d'exécution)

Mon plan est d'utiliser le crochet pour attraper la clé d'entrée, et ensuite utiliser keybd_event pour simuler le clavier. Mais j'ai quelques problèmes.

Le premier problème est que le programme peut correctement le bloc "A", mais si je frappe " A " sur le clavier une fois, le printf dans la fonction de rappel est exécutée deux fois, ainsi que le keybd_event. Donc, si j'ouvre un fichier txt, je clique sur " A " une fois, il y a deux 'B de l'entrée. pourquoi est-ce?

La deuxième question est que pourquoi le crochet à l'aide de WH_KEYBOARD_LL peut travailler sur d'autres processus sans une dll? J'ai pensé que nous avons dû utiliser une dll pour faire un hook global jusqu'à ce que j'ai écrit cet exemple...

#include "stdafx.h"
#include <Windows.h>
#define _WIN32_WINNT 0x050

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    BOOL fEatKeystroke = FALSE;

    if (nCode == HC_ACTION)
    {
        switch (wParam)
        {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
            PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
            if (fEatKeystroke = (p->vkCode == 0x41)) {     //redirect a to b
            printf("Hello a\n");
            keybd_event('B', 0, 0, 0);
            keybd_event('B', 0, KEYEVENTF_KEYUP, 0);
            break;
            }
            break;
        }
    }
    return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam));
}

int main()
{
    //Install the low-level keyboard & mouse hooks
    HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);

    //Keep this app running until we're told to stop
    MSG msg;
    while (!GetMessage(&msg, NULL, NULL, NULL)) {    //this while loop keeps the hook
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnhookWindowsHookEx(hhkLowLevelKybd);

    return(0);
}

Merci beaucoup!

Mondial crochets ne sont pas d'entrée, ils vous permettent de prévisualiser.
selon msdn.microsoft.com/en-us/library/windows/desktop/... - "...peut retourner une valeur différente de zéro pour éviter que le système de passer le message au reste de la chaîne de crochet ou de la procédure de fenêtre cible". Pour moi, empêchant le système de passer le message à la procédure de fenêtre cible ressemble exactement comme le blocage.
Pour ceux qui cherchent à obtenir que cela fonctionne, mais reçoit ERROR_HOOK_NEEDS_HMOD (1428): selon SetWindowsHookEx doc, "une erreur peut se produire si le hMod paramètre est NULL et le dwThreadId paramètre est égal à zéro". Par conséquent, vous devez spécifier hMod, mais dans ce cas, vous pouvez utiliser n'importe quelle valeur juridique, puisque aucune DLL est injecté de toute façon pour le bas niveau des crochets. Vous pouvez utiliser, par exemple, GetModuleHandle("kernel32.dll").

OriginalL'auteur user1722361 | 2014-04-09