【问题标题】:JNA KeyboardUtils.isPressed not working with arrow keysJNA KeyboardUtils.isPressed 不使用箭头键
【发布时间】:2019-08-18 17:20:39
【问题描述】:

我正在尝试创建一个调用 JNA 的 KeyboardUtils 类来检查 Windows 上的关键状态的示例(类似于 Win32 的 GetAsyncKeyState())。

这是我的代码:

package com.foo;

import com.sun.jna.platform.KeyboardUtils;
import java.awt.event.KeyEvent;

public class Main {
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                System.out.println("Watching for Left/Right/Up/Down or WASD.  Press Shift+Q to quit");
                while (true) {
                    try
                    {
                        Thread.sleep(10);
                        if (KeyboardUtils.isPressed(KeyEvent.VK_DOWN) || KeyboardUtils.isPressed(KeyEvent.VK_S) )
                        {
                            System.out.println("Down");
                        }
                        if (KeyboardUtils.isPressed(KeyEvent.VK_UP) || KeyboardUtils.isPressed(KeyEvent.VK_W) )
                        {
                            System.out.println("Up");
                        }
                        if (KeyboardUtils.isPressed(KeyEvent.VK_LEFT) || KeyboardUtils.isPressed(KeyEvent.VK_A) )
                        {
                            System.out.println("Left");
                        }
                        if (KeyboardUtils.isPressed(KeyEvent.VK_RIGHT) || KeyboardUtils.isPressed(KeyEvent.VK_D) )
                        {
                            System.out.println("Right");
                        }
                        if (KeyboardUtils.isPressed(KeyEvent.VK_Q) && KeyboardUtils.isPressed(KeyEvent.VK_SHIFT) )
                        {
                            break;
                        }
                    }
                    catch(Exception e)
                    { }
                }
                System.exit(0);
            }
        }.start();
    }
}

这可以正常工作并检测 WASD 键以及 Shift+Q。但是,永远不会检测到箭头键 Left/Right/Up/Down。

将代码转换为 C++ 并调用 Win32 GetAsyncKeyState() 确实可以使用箭头键。

根据网络,KeyEvent.VK_DOWN 的值与Win32 definition (40) 匹配。

知道为什么 JNA 没有正确检测到箭头键吗?

【问题讨论】:

  • 我还没有看到GetAsyncKeyState 的有效用例。你想完成什么?
  • @IInpectable - 我的用例是在立即模式下读取键状态,而不是使用来自 awt 或 swing 的 KeyEvents。这就是 GetAsyncKeyState 的目的(这是 Windows 上的 isPressed 调用)。
  • 我明白了,GetAsyncKeyState 做了什么。我不明白,你(或任何人)为什么要使用它。

标签: java winapi jna


【解决方案1】:

根据KeyboardUtils source codeKeyboardUtils 在任何平台上根本不支持箭头键。

KeyboardUtils 仅适用于 3 个键盘平台 - Windows、Mac 和 Linux。

在 Mac 上,isPressed() 根本没有实现,所有键码都返回 false,并且在初始化 KeyboardUtils 时会抛出 UnsupportedOperationException

在 Windows 和 Linux 上,KeyboardUtils 支持以下键:

  • VK_A - VK_Z
  • VK_0 - VK_9
  • VK_SHIFT
  • VK_CONTROL
  • VK_ALT
  • VK_META(仅限 Linux)

在 Windows 上,KeyboardUtils.isPressed()KeyEvent 键码转换为 Win32 虚拟键码(W32KeyboardUtils.toNative())并将它们传递给 GetAsyncKeyState()W32KeyboardUtils.isPressed())。但是箭头键没有被处理并被转换为虚拟键码 0,这不是一个有效的键码。

与 Linux 键码类似。

因此,要在 Windows 上检测箭头键,您必须自己调用 GetAsyncKeyState(),正如您已经发现的那样。

【讨论】:

    猜你喜欢
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 2011-10-27
    相关资源
    最近更新 更多