Java 在Windows操作系统上使用JNA捕获窗口事件

Java 在Windows操作系统上使用JNA捕获窗口事件,java,winapi,jna,Java,Winapi,Jna,我试图用JNA捕捉窗口打开和关闭事件。我的目标是获得窗口标题。应该可以通过从User32 lib调用来安装WH_CBT hook。此挂钩的回调函数为 默认情况下,有一个库不支持WH_CBT hook,我编写了自己的实现,但它不起作用。我仔细检查了CBTProc过程的签名,它看起来是正确的,但没有调用 我错过什么了吗 这是代码 public class CbtProcHook { private static volatile boolean quit; private static HHOOK

我试图用JNA捕捉窗口打开和关闭事件。我的目标是获得窗口标题。应该可以通过从User32 lib调用来安装WH_CBT hook。此挂钩的回调函数为

默认情况下,有一个库不支持WH_CBT hook,我编写了自己的实现,但它不起作用。我仔细检查了CBTProc过程的签名,它看起来是正确的,但没有调用

我错过什么了吗

这是代码

public class CbtProcHook {
private static volatile boolean quit;
private static HHOOK hhk;
private static WinUser.HOOKPROC sysCmdHook;

interface CbtProc extends WinUser.HOOKPROC {
    WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinDef.LPARAM lParam);
}

public static void main(String[] args) {
    final User32 lib = User32.INSTANCE;

    HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);

    sysCmdHook = (CbtProc) (nCode, wParam, lParam) -> {
        System.out.println("in callback. nCode=" + nCode + " wParam.intValue=" + wParam.intValue());
        quit = true;
        return lib.CallNextHookEx(hhk, 1, wParam, null);
    };

    //        5 = WH_CBT
    hhk = lib.SetWindowsHookEx(5, sysCmdHook, hMod, 0);
    System.out.println("hook installed");

    new Thread() {
        public void run() {
            while (!quit) {
                try {
                    Thread.sleep(500);
                    int error = Kernel32.INSTANCE.GetLastError();
                    if (error < 0) {
                        System.out.println("error=" + error);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.err.println("unhook and exit");
            lib.UnhookWindowsHookEx(hhk);
            System.exit(0);
        }
    }.start();
}

为什么要用1替换nCode,用NULL替换LPRAM? 另外,如果nCode小于零,则必须返回CallNextHookEx的结果,而无需进一步处理

sysCmdHook = (CbtProc) (nCode, wParam, lParam) -> {

    if(nCode<0)
          return lib.CallNextHookEx(hhk, nCode, wParam, lParam);

    System.out.println("in callback. nCode=" + nCode + " wParam.intValue=" + wParam.intValue());
    quit = true;
    return 0;
};

CBTProc的返回类型应为LRESULT。在您的情况下,lambda返回0。这是行不通的。这段代码你想说什么?@Mirian我是C开发人员,不是java。但很明显,您并没有像处理钩子那样处理钩子。如果ncode小于0,那么除了返回CallNextHook的结果和精确的参数外,您无需做任何事情。在那之后我甚至把println移了下来。@Mirian查看msdn链接。谢谢你的回复。我明白你的意思。不幸的是,即使在您进行了更改之后,也没有任何效果。从未调用sysCmdHook。我将再次更彻底地阅读msdn。您将只能捕获当前进程中的事件。挂接所有进程的事件需要一个基于DLL的回调过程,JNA不完全支持这个过程。您需要一些基于DLL的代码来实例化任何给定进程中的JVM。请稍后回复。但我不确定您是否正确。这个示例是在另一个示例的基础上构建的,它捕获键盘事件。该示例在应用程序之外完全有效,可以捕获系统中任何地方的按钮按下事件。低级键盘和鼠标挂钩对回调代码驻留的位置没有相同的要求。请理解。看来没有机会捕捉windows事件。试着用另一种方式解决我的任务。谢谢你,伙计