Могу ли я переместить окно другой программы в центр фокуса?

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

3 ответа

Решение

Вы не можете сделать это в чистом Java-коде, но вы можете использовать JNI. См. В Java Swing, как получить ссылку дескриптора окна Win32 (hwnd) на окно? о том, как получить ручку к окну. Затем вы можете сделать что-то вроде http://msdn.microsoft.com/en-us/library/ms633545 чтобы переместить его вперед.

Предостережение: это только для окон

Это невозможно в чистой Java, и в некоторых операционных системах невозможно даже получить чистую позицию других окон (например, удачи в том, что в OS X 10.4: OS X 10.4 не имеет никакого документированного средства для регистрации событий других окон... Есть "хаки", но они действительно хакерские, например, требуют, чтобы пользователь включил настройки "Разрешить вспомогательное устройство", для чего требуется пароль администратора OS X).

Я искал решение очень похожей проблемы. До сих пор я нашел один - очень хрупкий! - решение. Это работает для моего случая, потому что мой случай включает в себя запуск целых сессий с использованием java.awt.Robot без взаимодействия с пользователем, так что это может - или не может - работать для вашего случая.

Решение использует java.awt.Robot отправлять нажатия клавиш, как Alt+Tab вывести желаемое окно на передний план. Конечно, это хрупко по нескольким причинам:

  • Робот не может знать, как часто Alt+Tab необходимо отправить, чтобы получить желаемое окно на передний план. Окно одно во многих. Это решение работает, только если уже известно, какое окно с точки зрения Alt-Tab-счет это.
  • В зависимости от ОС, требуемые нажатия клавиш могут быть чем-то другим.

Если ОС и последовательность окон известны, то есть программа может заранее знать, сколько Alt-Tab нажатия клавиш, иногда это может быть решением.

Следующая программа Java демонстрирует, как это сделать. Если вызывается без аргументов, генерируется ровно один Alt+Tab нажатие клавиши. Если вызывается с аргументами, программа предполагает, что первый аргумент является числом, и генерирует столько же Alt+Tab нажатия клавиш, как указано этим числом.

Возможно, вы захотите немного поиграть со значениями синхронизации, приведенными в robot.delay() а также robot.setAutoDelay() для того, чтобы доставить лучший опыт на вашей машине. Подсказка: по крайней мере, в Linux, robot.setAutoDelay() должно быть меньше, чем задержка повторения клавиатуры, иначе ОС будет генерировать несколько Alt-Tab нажатия клавиш в очереди событий системы из-за повторения клавиш.

import java.awt.AWTException;
import java.awt.Robot;
import static java.awt.event.KeyEvent.VK_ALT;
import static java.awt.event.KeyEvent.VK_TAB;
import static java.lang.Integer.parseInt;

public class WindowSwitcher {
    public static void main(final String... args) throws AWTException {
        final int repeat = args.length != 0 ? parseInt(args[0]) : 1;
        final Robot robot = createRobot();
        robot.keyPress(VK_ALT);
        for (int i = 0; i < repeat; i++) {
            robot.keyPress(VK_TAB);
            robot.keyRelease(VK_TAB);
            robot.delay(500);
        }
        robot.keyRelease(VK_ALT);
    }
    public static Robot createRobot() throws AWTException {
        final Robot robot = new Robot();
        robot.setAutoWaitForIdle(true);
        robot.setAutoDelay(10);
        return robot;
    }
}
Другие вопросы по тегам