Getting Active Window Information in Java

Getting active window information in Java

Save yourself some pain and use JNA. You will need to download jna.jar and jna-platform.jar for the Win32 API. The pinvoke wiki and MSDN are useful for finding the right system calls.

Anyway, here is the code to print the title and process of the currently active window.

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);
}
}

How do I get the active window's application's name with JNA?

I've found that GetWindowModuleFilename doesn't really work most of the time. QueryFullProcessImageName, however, works just fine. Note that you still do need to OpenProcess the process to access the image file name.

Try this in a console application. It will print out the active window's image filename when you change the window.

import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.IntByReference;

public class Main {
public static void main(String[] args) throws Exception {
HWND prevFg = null;

while (true) {
Thread.sleep(200);

HWND fg = User32.INSTANCE.GetForegroundWindow();

// don't print the name if it's still the same window as previously
if (fg.equals(prevFg)) {
continue;
}

String fgImageName = getImageName(fg);
if (fgImageName == null) {
System.out.println("Failed to get the image name!");
} else {
System.out.println(fgImageName);
}

prevFg = fg;
}
}

private static String getImageName(HWND window) {
// Get the process ID of the window
IntByReference procId = new IntByReference();
User32.INSTANCE.GetWindowThreadProcessId(window, procId);

// Open the process to get permissions to the image name
HANDLE procHandle = Kernel32.INSTANCE.OpenProcess(
Kernel32.PROCESS_QUERY_LIMITED_INFORMATION,
false,
procId.getValue()
);

// Get the image name
char[] buffer = new char[4096];
IntByReference bufferSize = new IntByReference(buffer.length);
boolean success = Kernel32.INSTANCE.QueryFullProcessImageName(procHandle, 0, buffer, bufferSize);

// Clean up: close the opened process
Kernel32.INSTANCE.CloseHandle(procHandle);

return success ? new String(buffer, 0, bufferSize.getValue()) : null;
}
}

Clicking around my windows, the program prints out lines like these:

C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2017.3.5\bin\idea64.exe
C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2017.3.5\bin\idea64.exe

Find out what application (window) is in focus in Java

I'm afraid there's no java api for that. JVM does not know anything about the windows it does not manage. You'll probably have to use JNI and call this function

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

MSDN link

PS. THere is a GetWindowText function that you might want to use if you need to grab the title of the window.

This post has JNI examples that might be helpful for you.



Related Topics



Leave a reply



Submit