我已经实现了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);
}
}
答案 0 :(得分:0)
没有简单的方法来预测生成的输出(某些组合键不会产生任何输出)。如果Java生成KeyTyped事件,则生成的字符串将在事件中提供,但我认为没有任何API(Java或本机)为您提供键字串映射的击键。
答案 1 :(得分:0)
根据LowLevelKeyboardProc文档,您无法检测到Shift键的原因:
注意:当响应于其中的更改而调用此回调函数时 键的状态,则在 密钥的异步状态已更新。 因此, 密钥的异步状态无法通过调用确定 回调函数中的GetAsyncKeyState。