I work with autoitx4java in my java project.
That works fine until the window title I work with exists multiple times.
Imagine I have three windows with the title "MyAppTitle" open:
AutoItX x = new AutoItX();
int posX = x.winGetPosX("MyAppTitle");
Obviously a single value is returned. And it's the x-pos of the window "MyAppTitle" that I focused last.
It's no problem to get the handles of the windows. But most of the methods autoitx4java provides require the window title as parameter.
How can I access the windows with their handle? Or is there a better library I could use?
UPDATE: From the official AutoIt website:
When you have a handle you may use it in place of the title parameter
in any of the function calls that use the title/text convention.
But it doesn't work within the autoitx4java library.
Related
Problem: Determining if a window (by, say, hWnd) has the capability of being maximized or restored. Purpose of this is to programmatically send maximize/restore events to windows (for automation) but exclude windows which can't handle it.
Please consider the following two example windows while trying to determine this from GetWindowLong with GWL_STYLE:
a) The Discord client app (it is built with Electron). It has styles:
WS_CAPTION
WS_SIZEBOX
It does NOT have styles:
WS_SYSMENU
WS_MAXIMIZEBOX
This window does display a restore/maximize button and behaves properly when SW_MAXIMIZE/SW_RESTORE are posted to it.
b) The "Are you sure you want to quit?" prompt in InteliJ IDEA. It has styles:
WS_CAPTION
WS_SIZEBOX
WS_SYSMENU
It does NOT have style:
WS_MAXIMIZEBOX
This window does NOT display a restore/maximize button and does NOT behave properly when SW_MAXIMIZE/SW_RESTORE are posted to it (it crashes the whole IDE).
So, given these two examples, the following facts are true:
1) A window with WS_SIZEBOX style may not respond to SW_MAXIMIZE/SW_RESTORE messages properly (wasn't designed to);
2) A window without WS_SYSMENU nor WS_MAXIMIZEBOX may still respond to SW_MAXIMIZE/SW_RESTORE messages properly (draws system menu and/or buttons itself in a non-standard way)
3) Both of them have a native system menu that opens via title bar secondary-click and they correctly list maximize/restore as enabled or disabled (whatever matches their capability).
Given those two facts, how do I actually determine if a window can or cannot handle being maximized/restored? It seems it is not possible from window style alone, but I can't find anything in the Win32 API WinAPI to do this.
Note that I am deciding on whether to send SW_MAXIMIZE/SW_RESTORE by calling GetWindowPlacement and checking the showCmd.
Also note that I am using Java/JNA but I understand C++ or C# perfectly fine if you want to share code snippets.
I found that as a last resort I can use GetSystemMenu > GetMenuItemInfo to check if either Restore or Maximize system menu entry is enabled. So this is a decent fallback if the window has no WS_MAXIMIZEBOX style for whatever reason.
String cmd = "start calc.exe";
Process process = Runtime.getRuntime().exec(codeString);
I can call calculator out, but I wish to specify a accurate position like (200,300).
how can I rewrite my cmd String?
I know that java.awt.window can set a window or frame to the specific position.
Is there any method I can use to fill frame or window with my process?
There is no clean pure java solution because JDK does not provide API that can control non-java windows. So, if you want to can use JNI/JNA.
But I can suggest you a patch that will typically work.
Windows OS allows moving windows using keyboard. Try the following manually:
Win+R
type calc and press enter
press alt+space
press M
press enter
now use arrows to move the window. Press ESC to exit this mode.
All these actions can be implemented using java.awt.Robot.
So, you can run calculator and then immediately move its window where you want.
Well, this is not clear solution, but very simple one.
Expected Problems:
Alt+space is mapped to other, custom application
Other window that started together with calc overlaps it.
User will see that window is created somewhere and then quickly moved.
So, everything depends on how important all this for you. This solution is good as an exercise or demo but bad for real commercial application.
I'm developing a Swing application and I need to flash the Windows taskbar. I can't use frame.requestFocus() because I don't want to steal focus from any other application.
I don't know if it applies to newer versions of Windows, but the .toFront() method used to flash the window if none of the current VM's windows were in the foreground.
This means that calling frame.toFront() on a minimized frame would always make it flash...
JNIWrapper with its winpack extension can do what you want.
The Demo on the site shows it in action.
You can either force-minimize your GUI and .toFront-en it:
Gui.frame.setState(Frame.ICONIFIED);
for (int i = 0; i < 3; i++) {
Thread.sleep(10);
Gui.frame.toFront();
Thread.sleep(10);
Gui.frame.setVisible(false);
Thread.sleep(10);
Gui.frame.toBack();
Thread.sleep(10);
Gui.frame.setVisible(true);
}
// be creative!!
which sadly will remove the focus from the active window. You could find out the active window and reactivate it afterwards. But still, the flashing will only last for about three seconds.
...or get down to the really root of the matter by using a DLL-call on FlashWindow. Calling dlls is not possible with clean Java code, you'll need the help of other programming languages, possible e.g. with JNA. Other than that, you could also write your own program in another language and call it from your Java application. I'll give an example in AutoHotkey below:
AutoHotkey Code:
if 0 != 1 ; note: in ahk, 1 corresponds args[1] and 0 corresponds args.length
{
msgbox, There needs to be ONE parameter passed over to this file, which is the name of the window that should be flashed.
ExitApp
}
programName = %1%
winget, hWnd, ID, %programName%
DllCall("FlashWindow",UInt,hWnd,Int,True)
compiled into a file called flash.exe, put into your Java working directory, you can call it from any function:
Runtime.getRuntime().exec("./flash.exe \"" + MyJFrame.getTitle() + "\"");
Alternatively, one could use the AutoHotkey.dll and access it within the Javacode (there are guides on how to do it on the internet), so there'd be no need for any external exe files.
If you still have problems achieving the flashing in the windows taskbar, please let me know!
The best way to do this:
if (!isFocused()) {
setVisible(false);
setVisible(true);
}
Using Swing per se, you very probably can't; that's a Widnows specific thing.
Is there a way to copy text from a browser to my Java app ?
For example, at the left side of my screen I open a browser to point to a URL and shows the content of that page, it might be in a frame or CSS or simple html, on the right side of the screen I open a Java Swing application. I'm interested in certain parts of the browser window that shows some text, and I want my Java app [ without me doing anything ] to copy and paste the text into itself, can it be done ?
I know I can use JEditorPane or JTextPane and set it with an HTMLEditorKit, then load the text into the pane, but if the page uses Frames or some other complex ways, the text I get from the Pane is not what I see on the page, so I don't want to do it by loading the URL into my Java app, instead, I wonder if it can be done in the way I mentioned above ?
I think you're looking at the problem from the wrong angle. If what you want is to harvest a website, I suggest you have a look at the awesome library web-harvest. With a little Xpath wizardry you can get everything you want.
Doing what you describe would imply inter-process communication that seems like an overkill. There are more ways to download a web-page content than the browser.
You may try the following depending on your needs.
With java.awt.Robot you can either 1) Take an screenshot if what you neeed is the content ( without the text, just an image of the browser content ) or 2) Move your self into the browser and programatically press: CTRL-A + CTRL-C and return back to your swing app focus and programatically press: CTRL-V ( or CMD or whatever makes sense in your OS )
But again, this might or not work, depending on what you need.
I know a tool but i am not sure it meet your needs. Have you heard about selenium? http://seleniumhq.org/ It can replicate actions taken by the user in a browser and then manipulate them ussing java code. Have a look at the link it may be handy.
Using java.awt.Robot & a TextField will get the job done, not sure if there is any other way. Have robot press ctrl+a then ctrl+c, bring TextField into focus, and finally have robot press ctrl+v. Now from here you can create a button.setOnAction to save the TextField text into a string. Or you can use a change listener on the TextField setOnKeyReleased to do the same.
How can I insert some text into a textbox of another program using java. for example, yahoo messenger chatbox.
I'm not trying to make a yahoo bot, It's just an example of what I'm looking for.
Thank you!
As Jonathon noted in the comment, you can try using java.awt.Robot. But you'd need to know the exact location of target text field, and have it visible on the screen.
You can have something like:
Robot robot = new Robot();
robot.mouseMove(xCoord, yCoord);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.keyPress(50);
robot.keyPress(51);
Apart from that, you'd need the application to provide some native API to interact with its form, and use it via JNI.
You should use JNI (or better, JNA) and send Windows Messages to the other programs textbox. I assume the other program is not a Swing App (in which case only AWT Robot works), and by sending native windows messages you can reliable find the other programs textbox even if it doesn't has the focus or is hidden in the background.