Мне хотелось попробовать использовать 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 общаются здесь
-
Anonymous
1729839259
Anonymous
Мне хотелось попробовать использовать 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
Подробнее здесь: [url]https://stackoverflow.com/questions/79124587/native-hook-using-java-lang-foreign-in-jdk23[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия