Browse souce code repository at: https://github.com/jjYBdx4IL/java-evaluation/blob/master/src/test/java/jna/GlobalKeyboardHookTest.java
package jna;

import static org.junit.Assume.assumeTrue;

import com.github.jjYBdx4IL.utils.env.Surefire;
import com.privatejgoodies.common.base.SystemUtils;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinUser;
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.WinUser.MSG;

import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

import testgroup.RequiresIsolatedVM;

/**
 * inspired by:
 * https://github.com/java-native-access/jna/blob/master/contrib/w32keyhook/com/sun/jna/contrib/demo/KeyHook.java
 * 
 *
 */
@Category(RequiresIsolatedVM.class)
public class GlobalKeyboardHookTest {

    private static final Logger LOG = LoggerFactory.getLogger(GlobalKeyboardHookTest.class);
    
    private static HHOOK hhk = null;
    
    @Test
    public void test() throws IOException {
        assumeTrue(SystemUtils.IS_OS_WINDOWS);
        
        final User32 lib = User32.INSTANCE;
        HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
        LowLevelKeyboardProc keyboardHook = new LowLevelKeyboardProc() {
            @Override
            public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
                if (nCode >= 0) {
                    switch(wParam.intValue()) {
                        case WinUser.WM_KEYUP:
                        case WinUser.WM_KEYDOWN:
                        case WinUser.WM_SYSKEYUP:
                        case WinUser.WM_SYSKEYDOWN:
                            LOG.info("in callback, key=" + info.vkCode);
                    }
                }

                Pointer ptr = info.getPointer();
                long peer = Pointer.nativeValue(ptr);
                return lib.CallNextHookEx(hhk, nCode, wParam, new LPARAM(peer));
            }
        };
        hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
        
        if (Surefire.isSingleTestExecution()) {
            int result;
            MSG msg = new MSG();
            while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
                if (result == -1) {
                    LOG.info("error in get message");
                    break;
                }
                else {
                    LOG.info("got message");
                    lib.TranslateMessage(msg);
                    lib.DispatchMessage(msg);
                }
            }
        }
        
        lib.UnhookWindowsHookEx(hhk);
    }
}
-------------------------------------------------------------------------------
Test set: jna.GlobalKeyboardHookTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.19 s - in jna.GlobalKeyboardHookTest
test skipped