Получение активной информации о окне в Java

Я пытаюсь обновить свое приложение на Java, чтобы работать, только если активное окно с определенным именем. Я узнал, что это возможно с помощью JNI, но я понятия не имею, как именно это сделать. Я просто не мог найти описания или примера, которые могли бы объяснить это. Мой вопрос: как получить имя процесса текущего активного окна в Windows (через JNI или что-нибудь еще - я принимаю любое другое решение)?

Ответ 1

Спасите себя от боли и используйте JNA. Вам нужно download jna.jar и jna-platform.jar для API Win32. pinvoke wiki и MSDN полезны для поиск правильных системных вызовов.

В любом случае, вот код для печати названия и процесса текущего активного окна.

import static enumeration.EnumerateWindows.Kernel32.*;
import static enumeration.EnumerateWindows.Psapi.*;
import static enumeration.EnumerateWindows.User32DLL.*;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.ptr.PointerByReference;

public class EnumerateWindows {
    private static final int MAX_TITLE_LENGTH = 1024;

    public static void main(String[] args) throws Exception {
        char[] buffer = new char[MAX_TITLE_LENGTH * 2];
        GetWindowTextW(GetForegroundWindow(), buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window title: " + Native.toString(buffer));

        PointerByReference pointer = new PointerByReference();
        GetWindowThreadProcessId(GetForegroundWindow(), pointer);
        Pointer process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pointer.getValue());
        GetModuleBaseNameW(process, null, buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window process: " + Native.toString(buffer));
    }

    static class Psapi {
        static { Native.register("psapi"); }
        public static native int GetModuleBaseNameW(Pointer hProcess, Pointer hmodule, char[] lpBaseName, int size);
    }

    static class Kernel32 {
        static { Native.register("kernel32"); }
        public static int PROCESS_QUERY_INFORMATION = 0x0400;
        public static int PROCESS_VM_READ = 0x0010;
        public static native int GetLastError();
        public static native Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer);
    }

    static class User32DLL {
        static { Native.register("user32"); }
        public static native int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref);
        public static native HWND GetForegroundWindow();
        public static native int GetWindowTextW(HWND hWnd, char[] lpString, int nMaxCount);
    }
}

Ответ 2

Этот код работает с JNA 4.0

import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;

// see http://java-native-access.github.io/jna/4.0/javadoc/

public class EnumerateWindows {
    private static final int MAX_TITLE_LENGTH = 1024;

    public static void main(String[] args) throws Exception {
        char[] buffer = new char[MAX_TITLE_LENGTH * 2];
        HWND hwnd = User32.INSTANCE.GetForegroundWindow();
        User32.INSTANCE.GetWindowText(hwnd, buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window title: " + Native.toString(buffer));
        RECT rect = new RECT();
        User32.INSTANCE.GetWindowRect(hwnd, rect);
        System.out.println("rect = " + rect);
    }
 }

Ответ 3

Чтобы уточнить, что вы хотите обнаружить это:

1. A particular process is running.
2. Said process has an associated Window in the OS UI
3. The title of the window is "The Title I'm looking for"
4. The Window has 'focus' in the OS UI

Если это правильно, то извините, но я не могу помочь. Однако, если вы требования намного проще, так что вам нужно обнаружить, что какой-то конкретный процесс запущен, я бы предложил Sigar от Hyperic. Связанная с этим функция PTQL (http://support.hyperic.com/display/SIGAR/PTQL) позволяет вам искать процессы, которые удовлетворяют различным критериям, таким как аргументы, переданные им во время инициализации или их рабочий каталог. Если критерии, изложенные выше, верны, мне будет очень интересно узнать, можете ли вы это сделать. Удачи.