1
2
3
4
5 package oshi.driver.windows;
6
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11
12 import com.sun.jna.Pointer;
13 import com.sun.jna.platform.DesktopWindow;
14 import com.sun.jna.platform.WindowUtils;
15 import com.sun.jna.platform.win32.User32;
16 import com.sun.jna.platform.win32.WinDef.DWORD;
17 import com.sun.jna.platform.win32.WinDef.HWND;
18
19 import oshi.annotation.concurrent.ThreadSafe;
20 import oshi.jna.ByRef.CloseableIntByReference;
21 import oshi.software.os.OSDesktopWindow;
22
23
24
25
26 @ThreadSafe
27 public final class EnumWindows {
28
29 private static final DWORD GW_HWNDNEXT = new DWORD(2);
30
31 private EnumWindows() {
32 }
33
34
35
36
37
38
39
40 public static List<OSDesktopWindow> queryDesktopWindows(boolean visibleOnly) {
41
42 List<DesktopWindow> windows = WindowUtils.getAllWindows(true);
43
44 List<OSDesktopWindow> windowList = new ArrayList<>();
45
46 Map<HWND, Integer> zOrderMap = new HashMap<>();
47 for (DesktopWindow window : windows) {
48 HWND hWnd = window.getHWND();
49 if (hWnd != null) {
50 boolean visible = User32.INSTANCE.IsWindowVisible(hWnd);
51 if (!visibleOnly || visible) {
52 if (!zOrderMap.containsKey(hWnd)) {
53 updateWindowZOrderMap(hWnd, zOrderMap);
54 }
55 try (CloseableIntByReference pProcessId = new CloseableIntByReference()) {
56 User32.INSTANCE.GetWindowThreadProcessId(hWnd, pProcessId);
57 windowList.add(new OSDesktopWindow(Pointer.nativeValue(hWnd.getPointer()), window.getTitle(),
58 window.getFilePath(), window.getLocAndSize(), pProcessId.getValue(),
59 zOrderMap.get(hWnd), visible));
60 }
61 }
62 }
63 }
64 return windowList;
65 }
66
67 private static void updateWindowZOrderMap(HWND hWnd, Map<HWND, Integer> zOrderMap) {
68 if (hWnd != null) {
69 int zOrder = 1;
70 HWND h = new HWND(hWnd.getPointer());
71
72 do {
73 zOrderMap.put(h, --zOrder);
74 } while ((h = User32.INSTANCE.GetWindow(h, GW_HWNDNEXT)) != null);
75
76 final int offset = zOrder * -1;
77 zOrderMap.replaceAll((k, v) -> v + offset);
78 }
79 }
80 }