2011-06-17 77 views
28

我正在嘗試在Java中升級我的應用程序,以便僅在某個名稱的進程的窗口處於活動狀態時才能工作。我發現通過使用JNI這是可能的,但我不知道如何完成這個。我找不到任何可以解釋它的描述或例子。我的問題是 - 如何在Windows中獲取當前活動窗口的進程名稱(通過JNI或其他方式 - 我接受任何其他解決方案)?在Java中獲取活動窗口信息

+0

JNA([Java本地接入(http://jna.java.net/))是很容易,JNI使用,但對於任他們,JNI或JNA,你必須研究如何通過他們的教程和參考使用它們,然後你必須通過窗口API來查看正確的函數調用。這裏沒有捷徑。 –

回答

51

節省自己的一些痛苦和使用JNA。您將需要downloadjna.jarjna-platform.jar爲Win32 API。 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); 
    } 
} 
+0

很好地演示了 - 1+ :) –

+0

很棒!非常感謝:) – James

+0

從另一個問題到達這裏,樣品很好,節省了很多時間。 +1 – BigMike

5

該代碼可以使用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

僅適用於窗戶 – Martin