用 Java JNA 编写的关键侦听器。防止多次回调
Key listener written in Java JNA. Prevent multiple Callback
我使用下面的代码来监听全局按键事件:
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);
}
}
我想知道为什么我们按一次回调键会调用两次,我们如何防止它?possible.This是单次按键的例子
in callback, key= 70
in callback, key= 70
我不确定我是否有权在该主题中提出另一个问题,但问题是第一个问题结束,我不想创建另一个主题。所以为什么我们得到 keycode=70 而不是 VC_F = 0x0021。有什么办法只得到 VC_F code
VC_F = 0x0021;
该程序正在侦听多个消息:WM_KEYUP 和 WM_KEYDOWN
您应该只收听 WM_KEYDOWN。
相关问题:Keyboard Input & the Win32 message loop
MSDN 信息:https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280(v=vs.85).aspx
如果您需要更复杂的行为,那么您应该存储一些信息并查看是否会收到连续的消息。
我使用下面的代码来监听全局按键事件: 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);
}
}
我想知道为什么我们按一次回调键会调用两次,我们如何防止它?possible.This是单次按键的例子
in callback, key= 70
in callback, key= 70
我不确定我是否有权在该主题中提出另一个问题,但问题是第一个问题结束,我不想创建另一个主题。所以为什么我们得到 keycode=70 而不是 VC_F = 0x0021。有什么办法只得到 VC_F code
VC_F = 0x0021;
该程序正在侦听多个消息:WM_KEYUP 和 WM_KEYDOWN
您应该只收听 WM_KEYDOWN。
相关问题:Keyboard Input & the Win32 message loop
MSDN 信息:https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280(v=vs.85).aspx
如果您需要更复杂的行为,那么您应该存储一些信息并查看是否会收到连续的消息。