解决了的。请看下面我的答案。
在我的代码中,我试图重新Map键盘键。 z
-> s
. 我使用的是jna库5.6.0和jna平台5.6.0,但熟悉c语言的人也能理解我,因为jna使用的是user32和kernel32 dll中的winapi函数。
我的问题是newkey打印两次,在newkey之间出现oldkey。当我输入“z”时,它应该打印“s”,但它打印的是“szs”。
我的代码:
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;
public class ReMapper {
private static WinUser.HHOOK hHook;
final User32 user32Library = User32.INSTANCE;
WinDef.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
static WinUser.INPUT input = new WinUser.INPUT();
public void reMapOn() {
WinUser.LowLevelKeyboardProc keyboardHook = new WinUser.LowLevelKeyboardProc() {
@Override
public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinUser.KBDLLHOOKSTRUCT kbdllhookstruct) {
if (nCode >= 0) {
switch (wParam.intValue()) {
case WinUser.WM_KEYUP:
case WinUser.WM_KEYDOWN:
case WinUser.WM_SYSKEYUP:
case WinUser.WM_SYSKEYDOWN:
if (kbdllhookstruct.vkCode == 90) {
sendKey(83);
break;
}
default:
wParam.setValue(WinUser.WM_SYSKEYDOWN);
break;
}
}
Pointer ptr = kbdllhookstruct.getPointer();
long peer = Pointer.nativeValue(ptr);
return user32Library.CallNextHookEx(hHook, nCode, wParam, new WinDef.LPARAM(peer));
}
};
hHook = user32Library.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
int result;
WinUser.MSG msg = new WinUser.MSG();
while ((result = user32Library.GetMessage(msg, null, 0, 0)) != 0) {
if (result == -1) {
break;
} else {
user32Library.TranslateMessage(msg);
user32Library.DispatchMessage(msg);
}
}
}
static void sendKey(int keyCode) {
input.type = new WinDef.DWORD(WinUser.INPUT.INPUT_KEYBOARD);
input.input.setType("ki"); // Because setting INPUT_INPUT_KEYBOARD is not enough: https://groups.google.com/d/msg/jna-users/NDBGwC1VZbU/cjYCQ1CjBwAJ
input.input.ki.wScan = new WinDef.WORD(0);
input.input.ki.time = new WinDef.DWORD(0);
input.input.ki.dwExtraInfo = new BaseTSD.ULONG_PTR(0);
// Press
input.input.ki.wVk = new WinDef.WORD(keyCode); // 0x41
input.input.ki.dwFlags = new WinDef.DWORD(0); // keydown
User32.INSTANCE.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size());
// Release
input.input.ki.wVk = new WinDef.WORD(keyCode); // 0x41
input.input.ki.dwFlags = new WinDef.DWORD(2); // keyup
User32.INSTANCE.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size());
}
public static void main(String[] args) {
new ReMapper().reMapOn();
}
}
我的打印示例:
有人能帮我理解为什么会这样吗?
1条答案
按热度按时间hfyxw5xn1#
通过更改本机callback()函数的returnig值来解决。在将oldkey重设为newkey之后,我们应该显式返回newwindef.lresult(1);
以下是我所有更改后将“z”重新Map到“s”的工作代码:
现在它就像一个魔咒:)