Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Keylistener without window being open?

I'm trying to create an auto-clicker in Java(only language I know and I just learned Threads). I want to have the applet open in it's own window(not on a webpage), and I want to be able to start and stop the program with the spacebar without the window being selected so that I can use the auto-clicker on another program and be able to stop it without alt-f4ing a bunch of stuff.

Is there anything you can refer me to that can help me along with this? Or do you have any suggestions?

like image 957
Azreal Avatar asked Mar 30 '09 06:03

Azreal


Video Answer


2 Answers

Late answer but hopefully helpful :)

You can using JNA, it's a cakewalk!!

  1. get JNA (jna.jar)
  2. create your own mapping for User32 (User32.dll) in the form

    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. Just check out the following pages to get a clear idea of how things work under the hood:

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

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

  1. Check this page to see what are the key constants you can register a callback for

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

  1. Create a test program like this:
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 is an undocumented constant with value 0xFFFFFFFF

Sorry about the http links renamed into h**p :) Stackoverflow rules Stefano

like image 110
Stefano Avatar answered Oct 01 '22 18:10

Stefano


This might be out of the scope of a Java applet. In fact, global keyboard hooks are definitely out of the scope of simply using Java, but I can help you get moving in the right direction.

However, you have some hope. I'll point you into the direction of JNI (Java Native Interface), which will allow you to use native libraries. Now, since you want to stay in the Java world, I suggest not directly using JNI because you'll have to write some confusing native code (typically C, C++). There are several wrappers for JNI that allow you to use the functions but the native implementations are abstracted away, but a lot of these cost money.


So the best solution for you, I think, is JNA (Java Native Access). This allows you to directly call native libraries from within Java. (NOTE: The implementation not will be cross platform. You have to make separate implementations for Windows, Linux, etc.) There's a good example for Windows keyboard hooks in the examples on the project website.

As for opening it's own window not in a webpage, do you want the applet to not run within the browser but in its own separate process, or just be in a separate window and still rely on the browser window being open?

  • If you want to simply launch a new window and still require the browser to be open, then here's a good example:

    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();
        }
    });
    
  • If you want the applet to spawn a new process and run without the need of the browser, look into JavaFX.

like image 38
sudorandom Avatar answered Oct 01 '22 17:10

sudorandom