【问题标题】:Using jna to consume key events使用jna消费关键事件
【发布时间】:2012-02-08 14:16:11
【问题描述】:

在我正在编写的其中一个应用程序中,我需要使用某些关键事件,以便其他应用程序不会处理它们。

在我的代码中,我制作了一个 com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc,如下所示:

import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
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.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.KBDLLHOOKSTRUCT;
import com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinUser;

public class KeyHook implements Runnable{

private static volatile boolean quit = false;
private static HHOOK hhk;
private static LowLevelKeyboardProc keyboardHook;

private Main main;
User32 lib;
HMODULE hMod;
public boolean isHooked = false;

public KeyHook(final Main main) {
    this.main = main;
    lib = User32.INSTANCE;
    hMod = Kernel32.INSTANCE.GetModuleHandle(null);
    Native.setProtected(true);
}

@Override
public void run() {
    keyboardHook = new LowLevelKeyboardProc() {
        public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
            if (nCode >= 0 && main.getPane().getTabCount() > 0) {
                switch (wParam.intValue()) {
                    case WinUser.WM_KEYUP:
                        if(info.vkCode == main.getListenMouse()){
                            main.listen();
                            return new LRESULT(1);
                        }
                        else if(info.vkCode == main.getStopListenMouse()){
                            main.stopListening();
                            return new LRESULT(1);
                        }
                        else if(info.vkCode == main.getStart()){
                            main.start();
                            return new LRESULT(1);
                        }
                        else if(info.vkCode == main.getPause()){
                            main.pause();
                            return new LRESULT(1);
                        }
                        else if(info.vkCode == main.getStop()){
                            main.stopRunning();
                            return new LRESULT(1);
                        }
                        else if(info.vkCode == 0x7B){
                            main.nextTab();
                            return new LRESULT(1);
                        }
                        break;
                    case WinUser.WM_KEYDOWN:
                       break;
                    case WinUser.WM_SYSKEYUP:
                        break;
                    case WinUser.WM_SYSKEYDOWN:
                        quit = true;
                        break;
                }
            }
            return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
            //return new LRESULT(1);
        }
    };
    hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
}
}

当我在我的 proc 结束时返回一个新的 LRESULT(1) 时(最后注释掉的代码),所有的键盘事件都被消耗掉了。但是,当我将其替换为

return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());

应该如此,并且只尝试使用我想要使用的主键盘事件,它不会使用任何键盘事件。有谁知道为什么它不允许我消费我想要的事件或知道如何解决它?

【问题讨论】:

  • 只有当你不想想要消费一个事件时才需要调用next hook,当你想要时返回LRESULT(1) .也许您打算标记消耗性事件的代码实际上并未被调用?
  • @technomage:当我想将 LRESULT(1) 用于个别事件时,我确实会返回它。我要说的是,当我为单个事件执行此操作时,它不会消耗它。你链接到的那个问题是我刚才提出的问题,当我用 LRESULT(1) 替换 nextHook 时它解决了这个问题,但是这样做会消耗所有关键事件。
  • 您是否检查过代码流以确定您要使用的键输入(返回 LRESULT(1) 的情况)是否出现了?
  • 是的,键输入出现了,所有应该作为事件结果运行的代码都在发生,但由于某种原因,事件之后没有被消耗

标签: java keyboard jna keyboard-events key-events


【解决方案1】:

为了确保某个键被“使用”,您需要确保避免在给定键的所有事件变体(即 WM_KEYUP、WM_KEYDOWN 以及可能WM_CHAR。

某些应用程序可能会查找按键按下事件,其他应用程序可能会查找按键按下,而其他应用程序可能仅查找生成的字符输出,因此您必须使用与给定按键相关的 所有 事件才能正确地进行按键操作“消失”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多