我的代码是监听键盘键和打印控制台中的键代码。
import com.sun.jna.Pointer;
import com.sun.jna.platform.DesktopWindow;
import com.sun.jna.platform.WindowUtils;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.ptr.IntByReference;
import java.util.List;
public class KeyHook {
private static volatile boolean quit;
private static WinUser.HHOOK hhk;
private static WinUser.LowLevelKeyboardProc keyboardHook;
private static DesktopWindow myWindow;
public static void main(String[] args) {
List<DesktopWindow> listWindow = WindowUtils.getAllWindows(true);
listWindow.forEach(desktopWindow -> {
if (desktopWindow.getTitle().equals("My Window Title")) {
myWindow = desktopWindow;
System.out.println(myWindow.getTitle() + myWindow.getLocAndSize());
}
});
//Descriptor - a unique number of My Window instance
WinDef.HWND hwnd = myWindow.getHWND();
//Native pointer representation for this object, getValue() returns Process ID
final IntByReference pid = new IntByReference();
// Thread ID that created the My Window window
int myWindowThreadProcessId = User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid);
final User32 lib = User32.INSTANCE;
WinDef.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
keyboardHook = new WinUser.LowLevelKeyboardProc() {
@Override
public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinUser.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 WinDef.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;
WinUser.MSG msg = new WinUser.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);
}
}
有没有可能只对特定的第三方非java进程应用密钥钩子?对我来说是 private static DesktopWindow myWindow;
当我试图添加 myWindowThreadProcessId
进入 SetWindowsHookEx()
setwindowshookex参数图像
就像那样 hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, myWindowThreadProcessId);
钥匙钩根本不起作用。
也许有人知道是否有可能为一个特定的进程实现一个键钩子?
暂无答案!
目前还没有任何答案,快来回答吧!