Dav*_*vid 11 java api java-native-interface winapi jna
我正在进行双向私聊,这将在全屏游戏中运行.
这需要让用户在屏幕顶部键入半透明文本框,即使它没有焦点也是如此.
使用以下代码,我可以检测所有物理键,但使用虚拟键时却很困难.
SHIFT 被检测到.
2 被检测到.
然而,Shift + 2它们都被检测为单独的键(即使在我的键盘上[SHIFT+2]给出@).IE:程序输出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));
}
}
Run Code Online (Sandbox Code Playgroud)
它工作正常并输出按下的键,但不适用于Shift +组合.我意识到我可以做一个"Switch"并将Shift + 3更改为"£",但这不适用于不同的键盘.
我得到了它。经过很多很多个小时的搜索,我设法创建了一种方法,可以将组合转换为当前键盘布局上的组合。它不处理死键(例如重音),但它捕获了[SHIFT+Combinations]我需要它捕获的所有内容。
要使用它,请按如下方式调用它:
\n\ngetCharacter(int vkCode, boolean shiftKeyPressed);\nRun Code Online (Sandbox Code Playgroud)\n\n那么,观看这个魔术吧。如果我想获得SHIFT+3键盘上的内容(\xc2\xa3),我使用:
getCharacter(KeyEvent.VK_3, true);\nRun Code Online (Sandbox Code Playgroud)\n\n这是代码:
\n\npublic static char getCharacter(int vkCode, boolean shiftKeyPressed)\n{\n\n byte[] keyStates = new byte[256]; //Create a keyboard map of 256 keys\n\n if (shiftKeyPressed)\n {\n keyStates[16]=-127; //Emulate the shift key being held down\n keyStates[160]=-128; //This needs to be set as well\n }\n\n IntByReference keyblayoutID = User32.INSTANCE.GetKeyboardLayout(0); //Load local keyboard layout\n\n int ScanCode = User32.INSTANCE.MapVirtualKeyExW(vkCode, MAPVK_VK_TO_VSC, keyblayoutID); //Get the scancode\n\n char[] buff = new char[1];\n\n int ret = User32.INSTANCE.ToUnicodeEx(vkCode, ScanCode, keyStates, buff, 1, 0, _currentInputLocaleIdentifier);\n\n switch (ret)\n {\n case -1: //Error\n return (char) -1;\n\n case 0: //No Translation\n return (char) 0;\n\n default: //Returning key...\n return buff[0];\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n以下是声明:
\n\nfinal static int MAPVK_VK_TO_VSC = 0;\nstatic IntByReference _currentInputLocaleIdentifier; \n\nstatic interface User32 extends Library {\n\n public static User32 INSTANCE = (User32) Native.loadLibrary("User32", User32.class);\n\n\n IntByReference GetKeyboardLayout(int dwLayout);\n int MapVirtualKeyExW (int uCode, int nMapType, IntByReference dwhkl);\n\n boolean GetKeyboardState(byte[] lpKeyState);\n\n int ToUnicodeEx(int wVirtKey, int wScanCode, byte[] lpKeyState, char[] pwszBuff, int cchBuff, int wFlags, IntByReference dwhkl);\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n非常感谢 BrendanMcK,他帮助我找到了这个解决方案。
\n