我正在用Java编写一个覆盖图,显示多个窗口的信息。
我需要它跟踪它正在跟踪的窗口,为了做到这一点,我定期获取当前窗口的信息来更新我的覆盖层的位置。但我还需要知道窗口是否可见,如果不可见,我将隐藏覆盖层。理想情况下,我应该能够真实的完成所有这些工作,但我担心这对性能要求太高。
我和JNA一起做这一切
public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.load("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
HWND FindWindow(String lpClassName, String lpWindowName);
int GetWindowRect(HWND handle, int[] rect);
boolean IsWindowVisible(HWND handle); // always true if window exist
}
public static int[] getWindowInformation(String windowName) {
int[] rectangle = {0,0,0,0};
HWND hwnd = User32.INSTANCE.FindWindow(null, windowName);
User32.INSTANCE.GetWindowRect(hwnd, rectangle);
boolean res = User32.INSTANCE.IsWindowVisible(hwnd);
System.out.println(windowName + " is visible ? " + res);
return rectangle;
}
这是我的代码,你可以看到,我尝试了“IsWindowVisible”后,完全阅读了JNA的User32 API,但它没有做我想要的。
1条答案
按热度按时间mklgxw1f1#
从
User32
使用IsWindowVisible
的直觉是好的,JNA实际上已经在它的WindowUtils类中实现了这一点。布尔参数为
onlyVisibleWindows
。注意,这里的“可见”指的是窗口本身的状态,而不是它是否被最小化(可能有离屏或“零”坐标)或“在其他窗口之后”与“在其他窗口之上”,从而对用户可见。
如果指定窗口、其父窗口、其父窗口的父窗口等具有WS_VISIBLE样式,则返回值为非零值。否则,返回值为零。
因为返回值指定窗口是否具有WS_VISIBLE样式,所以即使该窗口完全被其他窗口遮挡,它也可能是非零的。
为了确定窗口是部分还是全部被遮挡,你必须使用Z顺序来评估它的
locAndSize
矩形相对于它前面的所有窗口的大小。你可以逐个像素地进行评估,也可以只评估角点,这取决于你想要如何处理部分被遮挡的窗口。JNA
getAllWindows()
方法返回封装以下字段的JNADesktopWindow
的列表(通过可见性过滤):在内部,您可以看到内部类
W32WindowUtils
中的实现,它使用发送到User32
的EnumWindows
函数的回调函数:我维护了基于JNA的OSHI项目,并通过
new SystemInfo().getOperatingSystem().getDesktopWindows()
实现了这个跨平台的项目,new SystemInfo().getOperatingSystem().getDesktopWindows()
在Windows上使用了上面的实现,并添加了来自其他函数的信息以获得窗口排序。OSHI的返回列表包括以下字段,并且返回的列表已经在order
中排序,以帮助您确定用户可见性: