2011-06-17 11 views
28

Próbuję uaktualnić moją aplikację w Javie, aby działała tylko wtedy, gdy aktywne jest okno procesu o określonej nazwie. Dowiedziałem się, że jest to możliwe przy użyciu JNI, ale nie mam pojęcia, jak dokładnie to zrobić. Po prostu nie mogłem znaleźć żadnego opisu ani przykładu, który by to tłumaczył. Moje pytanie brzmi: jak uzyskać nazwę procesu aktualnie aktywnego okna w systemie Windows (przez JNI lub cokolwiek innego - akceptuję każde inne rozwiązanie)?Uzyskiwanie aktywnych informacji o oknie w Javie

+0

JNA ([Java Native Dostęp] (http://jna.java.net/)) jest łatwiejszy w użyciu niż JNI, ale dla jednego z je, JNI lub JNA, musisz nauczyć się, jak z nich korzystać, korzystając z ich samouczków i odnośników, a następnie musisz przejrzeć interfejs API okna, aby uzyskać prawidłowe wywołanie funkcji. Tu nie ma skrótów. –

Odpowiedz

51

Zaoszczędź sobie trochę bólu i użyj JNA. Będziesz musiał downloadjna.jar i jna-platform.jar dla Win32 API. Wiki pinvoke i MSDN są przydatne do znajdowania właściwych wywołań systemowych.

W każdym razie tutaj jest kod do wydrukowania tytułu i procesu aktualnie aktywnego okna.

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

dobrze zademonstrowany - 1+ :) –

+0

Działa świetnie! Dziękuję bardzo :) – James

+0

przybył tutaj z innego pytania, miła próbka, oszczędza dużo czasu. +1 – BigMike

5

Ten kod działa z 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); 
    } 
} 
+0

Tylko dla okien – Martin