I'm looking to write a relatively simple key macro for my own edification and also for my own use.
I intend for it to be able to run in the background when I run other programs, and at the press of a button will enter certain text into the active window. To be more specific, I want to go in a video game and use it to automatically send messages instead of having to type them.
I Googled around a bit, but apparently I'm not using the right keywords because I'm not really sure where to start. The closest I came was finding the Keystroke class, but that appears to be used for receiving keystrokes, not sending them.
I would appreciate and info regarding, or directing me to a resource for, these issues (how to send keystrokes to windows and anything about targeting which window etc).
To send key strokes you can use java.awt.Robot
To Choose which window to activate you can look around for ws script (windows script) or old VB6 code and use it to make VB script (simple text file of extn .vbs)
Or you can junk all that and use http://www.autohotkey.com/ which has window activation, sending keys, doing things on press of certain keys (like Windows Key + B) or macros.
To get a window to activate I had made an exe long back, but no longer use it, can get it from http://sourceforge.net/projects/win-utils/files/Window-Position/rel%2001/ (but only get this if the others do not work as need to seperately get COMCTL32.ocx and install that
If you do not want to use autohotkey you can use Jini to call platform specific functions, with a wrapper to call correst OSes functions. Never done it my self, when i had to use it i would make a process to call a exe that made the window come the front.
Related
How can I disable OS-level keyboard shortcuts (e.g. Alt-Tab, Ctrl-Alt-Left/Right, etc.) on a [Ubuntu] Linux machine? I'm developing a full-screen Java Swing app and don't want the user to be able to task switch away from the program arbitrarily. It's not enough to toggle the "always on top" flag; users mustn't be allowed to switch workspaces, migrate focus or any other such things. The machine must function normally before and after the application is executed. Google says that this will require JNI or JNA but I'm looking for a bit more hand-holding.
There's no point in trying to do this in your application because any of these changes are going to need to be handled by X11 and/or the window manager since those are what respond to the commands. Assuming that you have control of the platform, choose a window manager which supports a kiosk mode. Then use the window manager's settings to start your application and enter kiosk mode.
Options for window managers which can do this include KDE or twm-kiosk.
(And if you don't have control of the platform, you're not likely to be able to have your application intercept things like ctrl-alt-backspace anyway.)
Edit:
In response to a scaled-down version of the question in which he's willing to let things like ctl-alt-backspace go and just wants most of the keys including alt-tab or other similar application switching key combinations, the following should work:
You should be able to do this using XLib's XGrabKeyboard method through JNI. This Java/XLib JNI keypress capture tutorial should be a good starting point. However, it uses XGrabKey which just passively listens for keys and does not prevent other applications from receiving them. You'll instead want to use XGrabKeyboard which actively snags all of the normal keyboard events (which, if the premise of this StackOverflow question is correct, includes the task switching keys).
Note that as a side-effect, key capture in Swing will also probably stop working because your Swing windows are going to be separate from the window you create in C. As such, you will probably have to use your JNI interface to get key presses to your program when needed. (Although I would definitely advise testing it first before writing the code.) You might be able to avoid this if you can get the window using Java AWT Native Interface to get the window ID. (Note that Swing is built on top of AWT, so this will work for Swing.) However, I'm not sure how to do this. It looks like you might be able to navigate the window tree by getting the root window from the Display and going from there to find your Window, but it's all kind of weird. It would be nice if the AWT NI just told you the window ID, but it doesn't look like it does that.
As this warning Reminder: XGrabKeyboard is not a security interface notes, this doesn't make it impossible for other programs to see the keys, but it seems likely that window managers will not be using XQueryKeyMap so it is likely to prevent task switching.
This is going to be a bit convoluted, and likely seem a bit pointless to many (if not all) of you.
I use Windows 7, mostly, though XP is also used.
I have a KVM, it accepts keyboard and mouse input, and is networked so that I can remotely input via mouse and keyboard. However, I wish to copy and paste text (even modifiers, such as alt, ctrl, and so forth).
The onscreen keyboard is fine for...you know, keyboarding, but I want to send keys (much like VBS does) through copy and paste.
At this time I've made a little VB script that lets me do this, but it has some extreme limitations, primarily in that it doesn't STOP once you get going. If the window looses focus, or it does something unexpected, bad things happen.
Imagine putting a line of commands that are meant to control a Windows computer, remotely, and it just control your terminal, because the window lost focus. I have no difficulty in giving the right window focus in the code, but a simple slip of the hand will break it. Ideally, I would only be sending those keystrokes to THAT window, regardless of what window is active.
I have been unable to find a way to do that through VBS, though perhaps it exists. I could simply loop, forcing that window to go active for each keystroke, but that doesn't ALWAYS work, as I sometimes need to use key combos, and I have no idea how I'd send an %{f4} one character at a time and still make it work.
So, finally, here's the question: How can I copy and paste test into a text field so that it ALWAYS goes to the window I want it to go to? Preferably it'll be usable in other windows (may have more than one instance open), should I want to do that, and it should be able to go a certain typing speed, as the application I use does crash if you send too much data at once (unclear how much is too much, but a single line is usually fine).
This isn't all that different from using a macro program, but I will be severely limited in what sort of application I can use. Scripts or java apps are about all I can get away with.
Thanks in advance!
Is there a way to detect key input when the window is not active? That is, another application is running but the program is triggered when say the F9 key is pressed or something along those lines.
Is that possible or is java not compatible for such functions? From what I found java can't get input unless it's the active window.
Note:
I typically use keylistener, which seems to stop working (with good reason) when I am not actively using the program.
It sounds like you want low level keyboard hooks.
Get global keyboard input with Java
It's not directly possible in Java (i.e. with pure Java code), but you could reference other libraries (or make your own) to acheieve this. A quick google search gives a lot of references and free/open libraries that can give you keyboard and mouse hooks (both very handy).
Hope that helps.
I have a windows application which has a complex GUI that I would like to hide from users. In order to do this, I would like to create a wrapper with an extremely simple interface that overlays this application and automates a number of actions when a user clicks a single button on the wrapper. (I hope "wrapper" is the proper term.) Is it possible to use Java to block input to the underlying application so that users cannot inadvertently mess up the automation? How would I go about this? Also, how can I automate key presses and clicks to the application without hijacking the mouse? Is this possible in Java?
I have looked at java.awt.Robot, but it appears to hijack the mouse.
I have also looked at AutoIT, but it too hijacks the mouse and does not integrate with Java.
Neither of these options seem powerful enough for what I need, but I do not know how else to proceed.
I recommend that automation via the GUI only as the last resort if you really have no other alternative.
If there is an API that your application exposes, I would try to use that. For example, if the GUI is implemented in one DLL and the logic in another, then you can use JNA to load your application logic DLL and invoke the application functions directly from java. Even better would be if your application exposes a COM/OLE interface - there are plenty of Java<>COM briges, that will alow you to call this interface directly, e.g. Jacob.
If you really have no choice but to automate via the GUI, then here's how to go about doing that:
Use JNA to access the windows shell API. You can then use ShellExecute to launch your wrapped application. Specifically, passing SW_HIDE as the window mode should help ensure that the application does not appear.
Use JNA to access the windows API FindWindow to find your application window. You can also make it invisible using the ShowWindow API, just in case step 1 did not work (not all applications are written to use the nCmdShow parameter.)
You can now post messages to the application window using PostMessage. You can send keystrokes and mouse events using windows messages. E.g. See WM_KEYUP, WM_LBUTTONDOWN.
Because the wrapped application window is made invisible, you don't need to "block" that application, The user simply cannot access it's GUI. But you can still programmatically send input to it.
My goal is assign a global hotkey (JIntellitype, JXGrabKey) that would pass an arbitrary selected text to a java app.
The initial plan is to utilize the java.awt.Robot to emulate Ctrl-C keypress and then get the value from clipboard.
Probably there's a more elegant solution?
EXAMPLE: Open Notepad, type in some text, select that text. Now, that text needs to be copied into a Java app.
I guess you want to implement a global input monitor, Java is not so straightforward to do the job. You may have to write an API hook and pack it in a DLL, then invoke it via JNI.
The Robot only sends events inside your JVM. I don't know of anything to send events out to the operating system. Though there is plenty of examples out there of making JNI calls to the windows API, it would then be platform specific.
I've gone with with Robot and that works just fine.