使用jna检测Shift键

时间:2011-09-23 05:47:11

标签: java java-native-interface jna

我已经实现了keyBoardHook,但是当shift键关闭时无法检测到按下的字符。

我尝试使用Windows的GetAsyncKeyState函数来检测何时按下shift键。但这不会处理shift + 2 = @。它会覆盖shift键并打印2的键码。

我可以获得每个键,但是Shift + 2被检测为单独的键(即使[SHIFT + 2]在键盘上给出@)。 IE:程序输出SHIFT和2,但不输出它们产生的内容:@。

问题:

如何检测换档键关闭时产生的字符。

我到目前为止编写的代码。

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);
}
}

2 个答案:

答案 0 :(得分:0)

没有简单的方法来预测生成的输出(某些组合键不会产生任何输出)。如果Java生成KeyTyped事件,则生成的字符串将在事件中提供,但我认为没有任何API(Java或本机)为您提供键字串映射的击键。

答案 1 :(得分:0)

根据LowLevelKeyboardProc文档,您无法检测到Shift键的原因:

注意:当响应于其中的更改而调用此回调函数时 键的状态,则在 密钥的异步状态已更新。 因此, 密钥的异步状态无法通过调用确定 回调函数中的GetAsyncKeyState。