Windows中的JNA键盘挂钩 [英] JNA Keyboard Hook in Windows

查看:157
本文介绍了Windows中的JNA键盘挂钩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Windows中安装了一个用于安装键盘钩子的JNA代码(使用JNA示例)。代码编译和一切,我得到了钩子安装(我成功地处理了钩子),我也可以成功卸载钩子。但是,当我按下键盘上的任意键时,回调永远不会被调用。这是我的代码(大部分是从JNA示例中获得的类型定义,直接转到main部分)

I have put together a JNA code for installing keyboard hook in Windows (using the JNA examples). The code compiles and everything, and I get the hook installed (I get handle to the hook successfully), also I can uninstall the hook successfully. However, the callback never get called when I press any key on the keyboard. Here is my code (most of it are type definitions got from the JNA examples, go to the "main" directly for my part)

import com.sun.jna.IntegerType;
import com.sun.jna.Pointer;
import com.sun.jna.PointerType;
import com.sun.jna.Structure;
import com.sun.jna.FromNativeContext;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Library;
import com.sun.jna.win32.W32APITypeMapper;
import com.sun.jna.win32.W32APIFunctionMapper;

import java.util.Map;
import java.util.HashMap;

public class HelloWorld {
    static Map UNICODE_OPTIONS = new HashMap() {
        {
            put("type-mapper", W32APITypeMapper.UNICODE);
            put("function-mapper", W32APIFunctionMapper.UNICODE);
        }
    };

    public static class LONG_PTR extends IntegerType {
        public LONG_PTR() { this(0); }
        public LONG_PTR(long value) { super(Pointer.SIZE, value); }
    }

    public static class UINT_PTR extends IntegerType {
        public UINT_PTR() { super(Pointer.SIZE); }
        public UINT_PTR(long value) { super(Pointer.SIZE, value); }
        public Pointer toPointer() { return Pointer.createConstant(longValue()); }
    }

    public static class ULONG_PTR extends IntegerType {
        public ULONG_PTR() { this(0); }
        public ULONG_PTR(long value) { super(Pointer.SIZE, value); }
    }

    public static class LRESULT extends LONG_PTR {
        public LRESULT() { this(0); }
        public LRESULT(long value) { super(value); }
    }

    public static class WPARAM extends UINT_PTR {
        public WPARAM() { this(0); }
        public WPARAM(long value) { super(value); }
    }

    public static class LPARAM extends LONG_PTR {
        public LPARAM() { this(0); }
        public LPARAM(long value) { super(value); }
    }

    public static class KBDLLHOOKSTRUCT extends Structure {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public ULONG_PTR dwExtraInfo;
    }

    static HANDLE INVALID_HANDLE_VALUE = new HANDLE() {
        { super.setPointer(Pointer.createConstant(-1)); }
        public void setPointer(Pointer p) {
            throw new UnsupportedOperationException("Immutable reference");
        }
    };

    public static class HANDLE extends PointerType {
        public Object fromNative(Object nativeValue, FromNativeContext context) {
            Object o = super.fromNative(nativeValue, context);
            if (INVALID_HANDLE_VALUE.equals(o))
                return INVALID_HANDLE_VALUE;
            return o;
        }
    }

    public static class HHOOK extends HANDLE { }
    public static class HINSTANCE extends HANDLE { }
    public static class HMODULE extends HINSTANCE { }

    public interface User32 extends StdCallLibrary  {
        User32 INSTANCE = (User32)Native.loadLibrary("user32", User32.class, UNICODE_OPTIONS);

        static final int WH_KEYBOARD_LL = 13;

        public static interface HOOKPROC extends StdCallCallback  {
            LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam);
        }

        HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HMODULE hMod, int dwThreadId);
        LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, LPARAM lParam);
        LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, Pointer lParam);

        boolean UnhookWindowsHookEx(HHOOK idHook);
    }

    public interface Kernel32 extends StdCallLibrary {
        Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class, UNICODE_OPTIONS);

        HMODULE GetModuleHandle(String name);
    }

    public static HHOOK hHook;
    public static User32.HOOKPROC lpfn;
    public static volatile boolean quit = false;

    public static void main(String[] args) throws Exception {
        HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
        System.out.println(hMod);

        lpfn = new User32.HOOKPROC() {
            public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam) {
                System.out.println("here");
                quit = true;
                return User32.INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam.getPointer());
            }
        };

        hHook = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, lpfn, hMod, 0);
        System.out.println(hHook);

        if(hHook != null)
            System.out.println("Keyboard hooked, type anything to quit");

        while(!quit) {
            Thread.sleep(100);
        }

        if(User32.INSTANCE.UnhookWindowsHookEx(hHook))
            System.out.println("Unhooked");

    }
}

我做过键盘/鼠标挂钩过去几次同时使用C ++和C#。这是我第一次使用Java,我只是不知道是否正确导入和映射了库。有什么想法?

I have done keyboard/mouse hooks several times using both C++ and C# in the past. This my first attempt with Java, and I just don't know whether I imported and mapped the library correctly. Any ideas?

谢谢。

推荐答案

看来你需要调用 GetMessage PeekMessage ,这很奇怪 - Hooks LowLevelKeyboardProc 。我不太了解API的这一部分来猜测原因。

It appears you need to call GetMessage or PeekMessage, which is odd - it is not mentioned in the documentation for Hooks or LowLevelKeyboardProc. I don't know enough about this part of the API to guess at the reason.

我刚才使用了示例类:

import com.sun.jna.examples.win32.*;

public class Callback {
  public static User32.HHOOK hHook;
  public static User32.LowLevelKeyboardProc lpfn;
  public static volatile boolean quit = false;

  public static void main(String[] args) throws Exception {
    W32API.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
    lpfn = new User32.LowLevelKeyboardProc() {
      public W32API.LRESULT callback(int nCode, W32API.WPARAM wParam,
          User32.KBDLLHOOKSTRUCT lParam) {
        System.out.println("here");
        quit = true;
        return User32.INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam
            .getPointer());
      }
    };
    hHook = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, lpfn, hMod,
        0);
    if (hHook == null)
      return;
    User32.MSG msg = new User32.MSG();
    while (!quit) {
      User32.INSTANCE.PeekMessage(msg, null, 0, 0, 0);
      Thread.sleep(100);
    }
    if (User32.INSTANCE.UnhookWindowsHookEx(hHook))
      System.out.println("Unhooked");
  }
}

这篇关于Windows中的JNA键盘挂钩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆