@antonwx

Как правильно зарегистрировать глобальную горячую клавишу в Java под Windows?

По мотивам статьи на хабре был написан (скопирован) следующий код:
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"});
    }
}

Клавишу он себе забирает, т.е. при запущенной программе F не передаётся другим программам, но вот в мою программу нажатие тоже не передаётся, вывода в консоль нет. Как исправить?
p.s. jintellitype использовать невозможно
  • Вопрос задан
  • 118 просмотров
Решения вопроса 1
@antonwx Автор вопроса
сам спросил - сам и отвечаю, а суть в том, что регистрировать надо клавишу в том же потоке, который слушает сообщения. User32.RegisterHotKey(null, 1, 0x000, KeyEvent.VK_F); идёт в run() и всё начинает работать.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы