Обнаружить клавишу Shift вниз, используя jna

Я реализовал keyBoardHook, но, тем не менее, не могу обнаружить нажатой символ, пока клавиша Shift не нажата.

Я попытался использовать функцию GetAsyncKeyState окон, чтобы определить, когда нажата клавиша Shift. Но это не обрабатывает сдвиг +2 = @. он переопределяет клавишу Shift и печатает код клавиши для 2.

я могу получить каждую клавишу, но Shift + 2 обнаруживаются как отдельные клавиши (хотя [SHIFT+2] дает @ на моей клавиатуре). IE: программа выводит как SHIFT, так и 2, но не то, что они выдают: @.

Вопрос:

Как я могу обнаружить символы, полученные при нажатии клавиши Shift.

Код, который я написал до сих пор.

public class Keyhook {
private static volatile boolean quit;
private static HHOOK hhk;
private static LowLevelKeyboardProc keyboardHook;

public static void main(String[] args) {
    final User32 lib = User32.INSTANCE;
    HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
    keyboardHook = new LowLevelKeyboardProc() {
        public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
            if (nCode >= 0) {
                switch (wParam.intValue()) {
                    case User32.WM_KEYUP:

                    break;
                    case User32.WM_KEYDOWN: 
                    if(lib.GetAsyncKeyState(160) == 1){
                         System.out.println(info.vkCode);    
                      }
                    break;
                    case User32.WM_SYSKEYUP:

                        break;
                    case User32.WM_SYSKEYDOWN:
                        System.err.println("in callback, key=" + info.vkCode);
                        if (info.vkCode == 81) {
                            quit = true;
                        }
                }
            }
            return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
        }
    };
    hhk = lib.SetWindowsHookEx(User32.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
    System.out.println("Keyboard hook installed, type anywhere, 'q' to quit");
    //noinspection ConstantConditions
    new Thread() {
        public void run() {
            while (!quit) {
                try {
                    Thread.sleep(10);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.err.println("unhook and exit");
            lib.UnhookWindowsHookEx(hhk);
            System.exit(0);
        }
    }.start();

    // This bit never returns from GetMessage
    int result;
    MSG msg = new MSG();
    while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
        if (result == -1) {
            System.err.println("error in get message");
            break;
        } else {
            System.err.println("got message");
            lib.TranslateMessage(msg);
            lib.DispatchMessage(msg);
        }
    }
    lib.UnhookWindowsHookEx(hhk);
}
}

1 ответ

Нет простого способа предсказать сгенерированный результат (некоторые комбинации клавиш не дают никакого результата). Если Java генерирует событие KeyTyped, сгенерированная строка будет предоставлена ​​в событии, но я не думаю, что есть какой-либо API (Java или нативный), который предоставляет вам комбинацию клавиш для сопоставления строк ключей.

Согласно документации LowLevelKeyboardProc, причина, по которой вы не можете обнаружить клавишу Shift:

Примечание. Когда эта функция обратного вызова вызывается в ответ на изменение состояния клавиши, функция обратного вызова вызывается до обновления асинхронного состояния клавиши. Следовательно, асинхронное состояние ключа не может быть определено путем вызова GetAsyncKeyState из функции обратного вызова.

Другие вопросы по тегам