Java 在Windows操作系统上使用JNA捕获窗口事件
我试图用JNA捕捉窗口打开和关闭事件。我的目标是获得窗口标题。应该可以通过从User32 lib调用来安装WH_CBT hook。此挂钩的回调函数为 默认情况下,有一个库不支持WH_CBT hook,我编写了自己的实现,但它不起作用。我仔细检查了CBTProc过程的签名,它看起来是正确的,但没有调用 我错过什么了吗 这是代码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
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事件。试着用另一种方式解决我的任务。谢谢你,伙计