Java Keylistener без открытого окна? - PullRequest
4 голосов
/ 30 марта 2009

Я пытаюсь создать автоматический кликер в Java (только язык, который я знаю, и я только что выучил Threads). Я хочу, чтобы апплет был открыт в своем собственном окне (не на веб-странице), и я хочу иметь возможность запускать и останавливать программу с пробелом без выбора окна, чтобы я мог использовать автоматический кликер в другой программе и сможете остановить его, не нажимая кучу всего.

Есть ли что-нибудь, на что вы можете направить меня, чтобы помочь мне в этом? Или у вас есть предложения?

Ответы [ 3 ]

6 голосов
/ 09 декабря 2010

Поздний ответ, но, надеюсь, полезно:)

Вы можете использовать JNA, это легкая прогулка !!

  1. получить JNA (jna.jar)
  2. создайте свое собственное сопоставление для User32 (User32.dll) в форме

    public interface User32 extends StdCallLibrary {
    User32 INSTANCE = (User32) Native.loadLibrary("User32", User32.class,   Options.UNICODE_OPTIONS);
    
    
    // dwWakeMask Constants
    public static final int QS_ALLEVENTS = 0x04BF;
    public static final int QS_ALLINPUT = 0x04FF;
    public static final int QS_ALLPOSTMESSAGE = 0x0100;
    public static final int QS_HOTKEY = 0x0080;
    public static final int QS_INPUT = 0x407;
    public static final int QS_KEY = 0x0001;
    public static final int QS_MOUSE = 0x0006;
    public static final int QS_MOUSEBUTTON = 0x0004;
    public static final int QS_MOUSEMOVE = 0x0002;
    public static final int QS_PAINT = 0x0020;
    public static final int QS_POSTMESSAGE = 0x0008;
    public static final int QS_RAWINPUT = 0x0400;
    public static final int QS_SENDMESSAGE = 0x0040;
    public static final int QS_TIMER = 0x0010;
    
    
    public static final int INFINITE =    0xFFFFFFFF;
    
    
    /*
    DWORD WINAPI MsgWaitForMultipleObjects(
    __in  DWORD nCount,
    __in  const HANDLE *pHandles,
    __in  BOOL bWaitAll,
    __in  DWORD dwMilliseconds,
    __in  DWORD dwWakeMask
    );*/
    
    
    int MsgWaitForMultipleObjects(int nCount, Pointer pHandles, boolean bWaitAll, int dwMilliSeconds, int dwWakeMask);
    
    
    /* fsModifiers vaues */
    public static final int MOD_ALT = 0x0001;
    public static final int MOD_CONTROL = 0x0002;
    public static final int MOD_NOREPEAT = 0x4000;
    public static final int MOD_SHIFT = 0x0004;
    public static final int MOD_WIN = 0x0008;
    
    
    /* BOOL WINAPI RegisterHotKey(
    __in_opt  HWND hWnd,
    __in      int id,
    __in      UINT fsModifiers,
    __in      UINT vk
    );
    */
    boolean RegisterHotKey(Pointer hWnd, int id, int fsModifiers, int vk);
    }
    
  3. Просто просмотрите следующие страницы, чтобы получить четкое представление о том, как все работает под капотом:

ч ** р: //msdn.microsoft.com/en-us/library/ms646309%28VS.85%29.aspx

ч ** р: //msdn.microsoft.com/en-us/library/ms684242%28VS.85%29.aspx

  1. Проверьте эту страницу, чтобы увидеть, какие ключевые константы вы можете зарегистрировать для обратного вызова для

ч ** р: //msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx

  1. Создайте такую ​​тестовую программу:
User32 user32 = User32.INSTANCE;
boolean res = user32.RegisterHotKey(Pointer.NULL, 9999, User32.MOD_ALT | User32.MOD_CONTROL, WINUSER.VK_LEFT);
if(!res)
  System.out.println("Couldn't register hotkey");

System.out.println("Starting and waiting");
user32.MsgWaitForMultipleObjects(0, Pointer.NULL, true, User32.INFINITE, User32.QS_HOTKEY);
System.out.println("Ending");

User32.INFINITE - недокументированная константа со значением 0xFFFFFFFF

Извините за ссылки http, переименованные в h ** p :) Правила Stackoverflow Stefano

2 голосов
/ 31 марта 2009

Это может выходить за рамки Java-апплета. На самом деле глобальные зацепки клавиатуры определенно выходят за рамки простого использования Java, но я могу помочь вам двигаться в правильном направлении.

Однако у вас есть надежда. Я укажу вам направление JNI (собственный интерфейс Java) , которое позволит вам использовать нативные библиотеки. Теперь, так как вы хотите остаться в мире Java, я предлагаю не использовать JNI напрямую, потому что вам придется написать какой-то запутанный нативный код (обычно C, C ++). Есть несколько оболочек для JNI, которые позволяют вам использовать функции, но собственные реализации абстрагированы, но многие из них стоят денег.


Так что, думаю, лучшим решением для вас будет JNA (Java Native Access) . Это позволяет вам напрямую вызывать собственные библиотеки из Java. (ПРИМЕЧАНИЕ. Реализация не будет кроссплатформенной. Вы должны сделать отдельные реализации для Windows, Linux и т. Д.) В примерах на веб-сайте проекта есть хороший пример хуков клавиатуры Windows.

Что касается открытия своего собственного окна не на веб-странице, хотите ли вы, чтобы апплет работал не в браузере, а в отдельном процессе, или просто находился в отдельном окне и по-прежнему полагался на то, что окно браузера открыто?

  • Если вы хотите просто запустить новое окно и по-прежнему требовать, чтобы браузер был открыт, то вот хороший пример:

    final Frame window = new Frame("This is the Frame's Title Bar!");
    window.add(new Label("This is the Frame."));
    window.setSize(300,200);
    window.setVisible(true);
    
    window.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent we){
            window.dispose();
        }
    });
    
  • Если вы хотите, чтобы апплет порождал новый процесс и выполнялся без необходимости браузера, посмотрите JavaFX .

0 голосов
/ 19 марта 2014

Я думаю, что вы можете сделать это, используя setVisible(false) метод. Окно будет там, но пользователь не сможет его увидеть.

...