用Java JNA编写的键侦听器.防止多次回拨 [英] Key listener written in Java JNA. Prevent multiple Callback
问题描述
我使用以下代码侦听全局键事件: Win32HookManager.java
I use the following code to listen to global key events: Win32HookManager.java
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.KBDLLHOOKSTRUCT;
import com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc;
import com.sun.jna.platform.win32.WinUser.MSG;
/** Sample implementation of a low-level keyboard hook on W32. */
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() {
@Override
public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
if (nCode >= 0) {
switch(wParam.intValue()) {
case WinUser.WM_KEYUP:
case WinUser.WM_KEYDOWN:
case WinUser.WM_SYSKEYUP:
case WinUser.WM_SYSKEYDOWN:
System.err.println("in callback, key=" + info.vkCode);
if (info.vkCode == 81) {
quit = true;
}
}
}
Pointer ptr = info.getPointer();
long peer = Pointer.nativeValue(ptr);
return lib.CallNextHookEx(hhk, nCode, wParam, new LPARAM(peer));
}
};
hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
System.out.println("Keyboard hook installed, type anywhere, 'q' to quit");
new Thread() {
@Override
public void run() {
while (!quit) {
try { Thread.sleep(10); } catch(Exception e) { }
}
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);
}
}
我想知道为什么一次按下回调键两次,我们如何防止它呢?这是一个按键的示例.
i am wondering why the callback key called twice time if we press it one time and how we can prevent it?is it possible.This is an example of a single keypress.
in callback, key= 70
in callback, key= 70
我不确定我是否有权在此主题中提出另一个问题,但问题是第一个问题要结束,并且我不想创建另一个主题.那么为什么我们得到键码= 70而不是VC_F = 0x0021.有什么办法只能得到VC_F代码
I am not sure if i had the permission to ask another question in this topic but the question is to close with the first one and i don't want to create an another topic. so Why we got keycode=70 instead of VC_F = 0x0021. is any way to got only the VC_F code
VC_F = 0x0021;
推荐答案
程序正在监听几条消息:WM_KEYUP和WM_KEYDOWN
The program are listening for several messages: WM_KEYUP and WM_KEYDOWN
您应该只听WM_KEYDOWN.
You should listen only for WM_KEYDOWN.
相关问题:键盘输入和Win32消息循环
MSDN信息: https ://msdn.microsoft.com/zh-CN/library/windows/desktop/ms646280(v = vs.85).aspx
如果您需要更复杂的行为,则应存储一些信息,并查看是否将接收连续的消息.
If you need a more complicated behavior then you should store some info and see for successive messages to be received.
这篇关于用Java JNA编写的键侦听器.防止多次回拨的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!