Here (http://www.desktop-macros.com/) is a program which records sequences of mouse clicks and key strokes on a PC and then plays it back to perform some user-defined actions.
Now, what I'd like to achieve is a bit more demanding: I'd like for example to launch a browser with mouse clicks, wait until it's started (i.e. its application screen is visible) and then again perform some mouse&keyboard actions.
Of course it would also be useful to obtain also other information, like position and dimensions of the window.
Is it possible to make such fancy OS-related operations (like checking whether an application is fully-loaded) with Java? Maybe there are some non-standard libraries with useful API?
If not, could you recommend some way/language of solving such an issue?
I use Autohotkey that has the command WinWait that waits for windows having the good title. But I rely on Send {Enter}, not on mouse, to do things.
Related
Background:
I was trying to program an auto clicker to click in the background to an application (Roblox, not trying to do anything malicious). I was able to get the window and perform commands like closing it. However, when trying to send clicks to the window it returns 0. (I'm using SendMessage so I don't activate the window)
Minimum reproducible example:
import win32gui
import win32con
import win32api
hwnd = win32gui.FindWindow(None, "Roblox")
while True:
lParam = win32api.MAKELONG(100, 100)
temp = win32gui.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, None, lParam)
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONUP, None, lParam)
print(temp)
Things I tried:
I tried changing the window to see if it was the wrong window, or if it didn't see the window
I tried sending the message normally:
lParam = win32api.MAKELONG(100, 100) # Get the coordinates and change to long
temp = win32gui.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, None, lParam) # Send message to handle
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONUP, None, lParam) # Release key from sent message to handle
I tried it with other windows, and it worked, but not for Roblox
I tried with other commands and it works, but clicks don't. This works: (So I know it's the right window)
temp = win32gui.SendMessage(hwnd, win32con.WM_CLOSE, 0, 0) # Close window with SendMessage
You cannot do that.
Let's start by rephrasing the problem statement to more easily follow along, why that is the case:
"How do I convince a program that has chosen to ignore mouse input messages—by decision or coincidence—to acknowledge mouse input messages?"
As it turns out, that part is actually solved. As the documentation for WM_LBUTTONDOWN notes:
If an application processes this message, it should return zero.
And zero you get, so there's no reason to question the fact that the message has been handled to the extent deemed necessary by the application. This probably falls down the "coincidence" branch, where the application just isn't interested in mouse messages any more than passing them on to DefWindowProc, the kitchen sink for all messages that aren't relevant enough to even ignore.
Key insight here is: A program that needs to process and respond to mouse input can decide to ignore mouse input messages1. (And clients that are based on mouse message handling can easily identify fake input messages, too, and respond by, y'know, not responding altogether.)
So, in essence, sending (or posting) fake mouse messages isn't going to work. Reliably. Ever.
Which leaves you with essentially 3 alternatives:
UI Automation
Accessing a custom automation interface
SendInput (a consolidated version combining keybd_event and mouse_event)
The first two options are listed for completeness only. They are commonly available for applications that actively support being automated. Games generally don't, and protecting against those avenues is easy, and cheap: An application doesn't have to do anything.
SendInput won't work, either. As far as the system is concerned, injected input is processed the same way as any other input (this blog post offers a helpful illustration). Specifically, when a mouse click is injected over a window, that window comes to the foreground. So that fails the requirement to have the application "in the background".
Even if that wasn't the case, injected input is easily and reliably identifiable. A low-level mouse hook is all that's required to get an MSLLHOOKSTRUCT, whose flags field gives this information readily away. With a low-level hook's ability to prevent input from being passed on to the system, a return 1; is all that's needed to filter out those input events.
And that covers all supported ways to automate a foreign application. It's a dead end so dead that it's not worth beating.
Now, if automating an application that runs in the background using fake input summarizes the requirements, then your only option is to run the application in a virtualized environment (which ensures that a click stays confined within the virtual environment and won't bring the application to the front). Keep in mind that all restrictions covered above still apply, and you cannot use any of the methods above. You would have to implement and install a custom mouse driver that generates input that's indiscernible from genuine hardware-sourced input events.
But even then, applications have ways of discovering that they are running in a virtualized environment, and refuse to operate when they do.
The bottom line is: Cheating is hard. Really hard. And your problem doesn't have an easy solution.
1 Mouse input messages are generated by the system as a convenience. They represent a useful (and lossy) abstraction over hardware input events. The full fidelity of those hardware input events is generally not required by "standard" applications.
Games, on the other hand, will usually use lower-level input processing infrastructure, such as Raw Input, and not even look at any of the higher-level processing artifacts.
We have a desktop client with several hundreds of users in our company. Sometimes it throws exceptions and crashes, but it's been hard to get the users to report their issues. To track these exceptions we are catching them and e-mailing the stacktrace and user specific data relating to the crash to a server wherefrom we then can view a log of all the crashes.
What would be really nice, is if we could log, not only the exception details, but also a screen recording video clip, of say the last 2 minutes up until the exception.
It shouldn't be very hard, all we need is some software that continuously records the screen and saves the video on drive, but erases everything older than a certain number of minutes. When the crash occurs we have can simply pick the current videoclip and attach it along with the exception details.
Anyone know of such a software, or anything similar that would solve our issue?
----------Solved:
I used both AndrewThompson´s and pjvds answers below. Andrews strategy outline, but with C# instead of Java, simply because our application is written in C#. The Code Project article pjvds linked helped me on how to do it in C#.
Here is one strategy:
Define a ScreenGrab object that encapsulates a BufferedImage and other relevant information (e.g. the time in millis or the mouse location).
Gain a screenshot using either the Robot or by establishing a BufferedImage the size of the content pane, and painting the content pane to the Graphics instance obtained from the image.
Create a ScreenGrab object and add it to an ArrayList
If the array list has exceeded a certain size, delete the first ScreenGrab in the list.
Rinse & repeat, perhaps at 2FPS, until an error occurs.
Either:
Use an adapted version of JpegImagesToMovie (uses the JMF) to transform the images (with pseudo mouse drawn in) to a MOV.
Zip all the ScreenGrab objects and send the archive instead.
Tweaks on this technique. The advantage of sending the ScreenGrab archive are multiple.
It can record the GUI perfectly, without the 'lossy' effect typical of JPEG compression.
If the user leaves the computer, neither the screen nor mouse position will change. So compare each one to the last and if the details are the same, skip storing it. The MOV would have to be at constant frame rate, but the Zip of custom objects could record at whatever rate best suits the user activity.
I remember I tried some code from a Code Project article years ago to accomplish the same. Capture Activities on Screen in a Movie.
We removed it from our software a release later due a lot of complains. People don't like it when their boss records their screen ;-)
I want to do in an Android application what I can do very easily in a "common" Java application : in a function triggered by a click on a menu item, I want to display a modal dialog box in which either the user can enter a text or choose between two or three answers (typically "yes", "no" and "cancel"). Once the user has made his input, the function can continue according to the choice made.
With the Fragment class, I can display the dialog box. The problem is that it only appears after the completion of the function triggered by the user's click. This means that the code depending on the user input has to be executed in the class derived from the Fragment class. And this has two disadvantages :
- it's more complex because a communication between the two objects has to be implemented,
- the reuse of the class is not easy since it's customized to communicate with only one class. Of course, it's possible to implement multiple communications towards as many class as we want, but the complexity will be even worse.
Is it possible to do what I want to do in a more simple way?
Thanks in advance for the time you will spend trying to help me.
Using a modal dialog is not allowed in android applications due to reasons like
A phone could go unattended for a long time. If a modal dialog pops up in that time, the app will be blocked, until the user attends the phone and dismisses the modal dialog. This will amount to loss in valuable processing time.
Even when the user is operating the phone, an app should not be blocked as a phones hardware configuration is far less than desktops and every millisecond of processing time is important.
I may be missing other points but these are the important ones.
So you should consider using callbacks to continue processing users input.
Maybe try to use http://developer.android.com/reference/android/app/Fragment.html#getActivity()
I am looking to right an application that limits the number of times a user can print something, its there anything in Java that will allow me to control the printing dialogue to this aim?
Im going to look into these:
http://www.wildcrest.com/Software/J2PrinterWorks/documentation/J2Printer14.html
http://www.softframeworks.com/products/products.php
This is probably something you'll need to implement yourself as it is too-specific a requirement to have been included in the JDK's API.
Assuming you've developed a standalone Swing application you could consider using the Preferences class to store the number of times a user has printed a document for a given date. On Windows this translates to storing information in the registry and is therefore "hidden" from the user to a certain extent, but would allow you to reset the value in an emergency using regedit.
The advantage of this approach is that the user cannot circumvent the print-threshold by simply restarting the application.
I decided to go with J2Printer. I allows the suppression of the print dialogue.
I'm wandering myself what component is the best for displaying fast search results in swing. I want to create something like this, make a text field where user can enter some text, during his entering I'll improve in back end fast search on database, and I want to show data bellow the text box, and he will be able to browse the results and on pres enter result will be displayed in table. So my question is is there any component which already have this logic for displaying?
Or is it's not, what is the best way to implement that.
This search will be something what ajax gives me on web, same logic same look and feel, if it's possible on desktop application.
Are you looking for something like an AutoComplete component for Java Swing?
SwingX has such a component. See here for the JavaDoc. It has a lot of utility methods to do various things, i.e. auto-completing a text box from the contents of a JList.
I strongly, strongly recommend that you take a look at Glazed Lists - this is one of the finer open source Java libraries out there, and it makes the bulk of what you are asking about super easy.
You will have to first attach a listener to the JTextFields Document to be notified whenever the user types in the field (or changes it).
From there, you can fire off any server-side code you need. The results of that can be used to update a listbox.
A few things to keep in mind:
The code to do the search against the backend must be in another thread
The code that updates the list box should update the list box's model
You will need to manage all your backend search results so that you only update the listbox with the most recent result (e.g. user types 'A', backenf searches for that. Meanwhile, user has typed 'C', kicking off a backend search for 'AC'. You need to ensure the results from the 'A' search dont' make it to the listbox if the 'AC' search results are available).
Use Hibernate Search.
The SwingHack (http://oreilly.com/catalog/9780596009076/) book has an example of this.
In the interest of killing two birds with one stone: have a separate indexing thread. This will:
Improve the speed of searches whenever they are executed.
Improve the responsiveness of the UI since indexing is happening in a separate thread.
Of course, exactly how you perform the indexing will vary widely depending on your particular application. Here is a good place to start researching: Search Indexing. And please, ignore the reference to Web 3.0 [sic].
It is possible of course. It is simple too. For drop down list of terms just use popup menu. This is simple. The background processing of entered text is simple too. Enjoy!