Мне хотелось попробовать использовать NativeHook, который можно полностью написать на Java, вместо JNativeHook, поэтому я написал тестовый код.
Однако результат всегда один и тот же, независимо от того, какую клавишу я нажимаю.
/>Может кто-нибудь сказать мне, как получить правильный код ключа?
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class hook_test {
private static final int WH_KEYBOARD_LL = 13;
private static final int WM_KEYDOWN = 0x0100;
private static long hook;
private static MethodHandle callNextHookEx;
void main() throws Throwable {
System.loadLibrary("user32");
Linker linker = Linker.nativeLinker();
SymbolLookup user32Lookup = SymbolLookup.loaderLookup();
MethodHandle setWindowsHookEx = linker.downcallHandle(user32Lookup.find("SetWindowsHookExA").orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT));
callNextHookEx = linker.downcallHandle(user32Lookup.find("CallNextHookEx").orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG));
MethodHandle getMessage = linker.downcallHandle(user32Lookup.find("GetMessageA").orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.JAVA_INT));
MethodHandle unhookWindowsHookEx = linker.downcallHandle(user32Lookup.find("UnhookWindowsHookEx").orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_LONG));
MethodHandle hookProcHandle = MethodHandles.lookup().findStatic(hook_test.class, "hookProc", MethodType.methodType(long.class, int.class, long.class, long.class));
MemorySegment hookProcAddress = linker.upcallStub(hookProcHandle, FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG), Arena.ofAuto());
hook = (long) setWindowsHookEx.invoke(WH_KEYBOARD_LL, hookProcAddress, MemorySegment.NULL, 0);
if (hook == 0) {
System.out.println("Failed to set hook");
return;
}
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
if (hook != 0)
unhookWindowsHookEx.invoke(hook);
} catch (Throwable t) {
System.err.println(t.getMessage());
}
}));
try (Arena arena = Arena.ofAuto()) {
MemorySegment msg = arena.allocate(28);
while ((int) getMessage.invoke(msg, MemorySegment.NULL, 0, 0) != 0) {
}
}
}
public static long hookProc(int code, long wParam, long lParam) {
if (code >= 0) {
if (wParam == WM_KEYDOWN)
System.out.printf("int code:%s\tlong wParam:%s\tlong lParam:%s\n", code, wParam, lParam);
}
try {
return (long) callNextHookEx.invoke(hook, code, wParam, lParam);
} catch (Throwable t) {
System.err.println(t.getMessage());
return 0;
}
}
}
Я ожидал, что даже если правильный код ключа не будет получен, из lParam будет выводиться другое значение для каждого ввода ключа. Однако когда я пытался его запустить, все значения были одинаковыми и менялись каждый раз, когда я его запускал.
int code:0 long wParam:256 long lParam:1059701387608
int code:0 long wParam:256 long lParam:1059701387608
int code:0 long wParam:256 long lParam:1059701387608
int code:0 long wParam:256 long lParam:1059701387608
Подробнее здесь: https://stackoverflow.com/questions/791 ... n-in-jdk23
Собственный перехват с использованием java.lang.foreign в JDK23 ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Использование java.lang.foreign для замены JNativeHook – Как обращаться с KBDLLHOOKSTRUCT
Anonymous » » в форуме JAVA - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Использование java.lang.foreign для замены JNativeHook – Как обращаться с KBDLLHOOKSTRUCT
Anonymous » » в форуме JAVA - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Использование java.lang.foreign для замены JNativeHook – Как обращаться с KBDLLHOOKSTRUCT
Anonymous » » в форуме JAVA - 0 Ответы
- 7 Просмотры
-
Последнее сообщение Anonymous
-