A
A
antonwx2019-06-02 21:35:13
Java
antonwx, 2019-06-02 21:35:13

How to correctly register a global hotkey in Java under Windows?

Based on the article on Habré, the following code was written (copied):
HotkeyManager.java:

import java.awt.event.KeyEvent;

public class HotkeyManager extends Thread {
    public static void register() {
        User32.RegisterHotKey(null, 1, 0x000, KeyEvent.VK_F);
        new HotkeyManager().start();
    }

    public HotkeyManager() {

    }

    @Override
    public void run() {
        MSG msg = new MSG();
        while (true) {
              while (User32.PeekMessage(msg, null, 0, 0, User32.PM_REMOVE)) {
                   if (msg.message == User32.WM_HOTKEY) {
                       System.out.println("Hotkey pressed with id: " + msg.wParam);
                   }
              }

              try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

User32.java:
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Pointer;
import com.sun.jna.win32.W32APIOptions;

public class User32 {
    static {
        Native.register(NativeLibrary.getInstance("user32", W32APIOptions.DEFAULT_OPTIONS));
    }

    public static final int MOD_ALT = 0x0001;
    public static final int MOD_CONTROL = 0x0002;
    public static final int MOD_SHIFT = 0x0004;
    public static final int MOD_WIN = 0x0008;
    public static final int WM_HOTKEY = 0x0312;
    public static final int PM_REMOVE = 0x0001;

    public static native boolean RegisterHotKey(Pointer hWnd, int id, int fsModifiers, int vk);
    public static native boolean UnregisterHotKey(Pointer hWnd, int id);
    public static native boolean PeekMessage(MSG lpMsg, Pointer hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);

}

MSG.java:
import java.util.Arrays;
import java.util.List;

import com.sun.jna.Pointer;
import com.sun.jna.Structure;

public class MSG extends Structure {
    public Pointer hWnd;
    public int lParam;
    public int message;
    public int time;
    public int wParam;
    public int x;
    public int y;

    @Override
    protected List getFieldOrder() {
        return Arrays.asList(new String[]{"hWnd", "lParam", "message", "time", "wParam", "x", "y"});
    }
}

He takes the key for himself, i.e. when the program is running, F is not transmitted to other programs, but the click is not transmitted to my program either, there is no output to the console. How to fix?
ps jintellitype cannot be used

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
antonwx, 2019-06-02
@antonwx

I asked myself - I answer myself, but the point is that you need to register a key in the same thread that listens to messages. User32.RegisterHotKey(null, 1, 0x000, KeyEvent.VK_F); goes to run() and everything starts working.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question