我正在开发可在全屏游戏中运行的双向私有(private)聊天。
这是让用户在屏幕顶部的半透明文本框中输入内容所必需的即使它没有焦点。
使用以下代码,我可以检测到所有物理键,但很难检测到虚拟键。
检测到SHIFT
。
2
被检测到。
但是 Shift + 2
被检测为两个单独的键(即使 [SHIFT+2]
在我的键盘上给出了 @
)。 IE:程序同时输出 SHIFT 和 2,但不输出它们产生的结果:@
。
问题是,如何根据键盘转换为字符? 例如:
- 在英式键盘上,SHIFT+2 会给我
"
(引号)。 - 在美式键盘上,SHIFT +2 会给我
@
。
如何根据键盘转换为特定字符?
这是目前的代码:
static interface User32 extends Library {
public static User32 INSTANCE = (User32) Native.loadLibrary("User32", User32.class);
short GetAsyncKeyState(int key);
short GetKeyState(int key);
IntByReference GetKeyboardLayout(int dwLayout);
int MapVirtualKeyExW (int uCode, int nMapType, IntByReference dwhkl);
boolean GetKeyboardState(byte[] lpKeyState);
int ToUnicodeEx(int wVirtKey, int wScanCode, byte[] lpKeyState, char[] pwszBuff, int cchBuff, int wFlags, IntByReference dwhkl);
}
public static void main(String[] args) {
long currTime = System.currentTimeMillis();
while (System.currentTimeMillis() < currTime + 20000)
{
for (int key = 1; key < 256; key++)
{
if (isKeyPressed(key))
getKeyType(key);
}
}
}
private static boolean isKeyPressed(int key)
{
return User32.INSTANCE.GetAsyncKeyState(key) == -32767;
}
private static void getKeyType(int key)
{
boolean isDownShift = (User32.INSTANCE.GetKeyState(VK_SHIFT) & 0x80) == 0x80;
boolean isDownCapsLock = (User32.INSTANCE.GetKeyState(VK_CAPS)) != 0;
byte[] keystate = new byte[256];
User32.INSTANCE.GetKeyboardState(keystate);
IntByReference keyblayoutID = User32.INSTANCE.GetKeyboardLayout(0);
int ScanCode = User32.INSTANCE.MapVirtualKeyExW(key, MAPVK_VK_TO_VSC, keyblayoutID);
char[] buff = new char[10];
int bufflen = buff.length;
int ret = User32.INSTANCE.ToUnicodeEx(key, ScanCode, keystate, buff, bufflen, 0, keyblayoutID);
switch (ret)
{
case -1:
System.out.println("Error");
break;
case 0: // no translation
break;
default:
System.out.println("output=" + String.valueOf(buff).substring(0, ret));
}
}
它工作正常并输出按下的键,但不适用于 Shift + 组合。我意识到我可以执行“切换”并将 Shift+3 更改为“£”,但这不适用于不同的键盘。
最佳答案
尝试使用JIntelliType图书馆代替。它比 JNA 使用起来简单得多,它应该能够执行 SHIFT + key (MOD_SHIFT)。您可能遇到的唯一问题是检测 3
,但这很容易解决(例如通过 KeyListener 打印键的代码)。
关于java - 使用 JNA (JAVA) 的 GetAsyncKeyState 和 VirtualKeys/特殊字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6237250/