1

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

在我的代码中,我制作了一个 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);
}
}

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

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

应该是这样,并且只尝试使用我想要使用的主键盘事件,它不会消耗任何键盘事件。有谁知道为什么它不会让我消费我想要的事件,或者知道如何解决它,所以它会?

4

1 回答 1

2

为了确保某个键被“使用”,您需要确保避免对给定键的所有事件变体(即 WM_KEYUP、WM_KEYDOWN 和可能的 WM_CHAR)调用下一个挂钩(即返回 LRESULT(1))。

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

于 2012-01-24T15:28:33.273 回答