是否可以检测窗口遮挡
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以检测窗口遮挡相关的知识,希望对你有一定的参考价值。
使用AWT,我想通过在隐藏窗口时停止绘制到屏幕来保存像flash一样的资源。但首先,我需要一种方法来检测Frame是否被一个或多个其他窗口完全覆盖。 Windows可能不是来自同一个应用程序,所以我不能只是总结他们的形状。
所以问题是,是否可以检测窗口是否被其他应用程序的其他窗口覆盖?
答案
一切皆有可能只需要一些创造力和努力工作:)
我希望你知道Java可以调用本机Windows API(这不是非常高性能的vise,但我们只有这种方式),为此我们可以使用JNA lib,这将使我们能够访问本机共享库。
我已经做了一些快速的概念检查,这个代码只检查活动窗口是否完全覆盖了java应用程序窗口,但是你可以迭代可见窗口并计算区域,JNA也提供了访问权限。
对于我的演示项目,我使用了这些JNA依赖项:
compile("net.java.dev.jna", "jna", "4.5.0")
compile("net.java.dev.jna", "jna-platform", "4.5.0")
我的主要课程:
package com.sauliuxx.inc;
import com.sauliuxx.inc.workers.ActiveWindowChecker;
import com.sun.jna.platform.win32.WinDef;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* The type App.
*/
public class App extends Frame implements ActionListener {
private final String title = "Demo123";
private Label sizeLabel;
private Label positionLabel;
private Label visibleLabel;
BlockingQueue<WinDef.RECT> q =
new LinkedBlockingQueue<>();
private App() {
this.setTitle(title);
this.setLayout(new BorderLayout());
this.setSize(500, 500);
Panel infoPanel = new Panel();
sizeLabel = new Label(this.getSize().height + " X " + this.getSize().width);
infoPanel.add(sizeLabel);
positionLabel = new Label("X: " + this.getLocation().getX() + " Y: " + this.getLocation().getY());
infoPanel.add(positionLabel);
visibleLabel = new Label(this.isVisible() ? "true" : "false");
infoPanel.add(visibleLabel);
this.add(infoPanel, BorderLayout.PAGE_END);
Timer timer = new Timer(250, this);
timer.start();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.addComponentListener(new ComponentListener() {
@Override
public void componentResized(ComponentEvent componentEvent) {
sizeLabel.setText(componentEvent.getComponent().getSize().height + " X " + componentEvent.getComponent().getSize().width);
}
@Override
public void componentMoved(ComponentEvent componentEvent) {
positionLabel.setText("X: " + componentEvent.getComponent().getLocation().getX() + " Y: " + componentEvent.getComponent().getLocation().getY());
}
@Override
public void componentShown(ComponentEvent componentEvent) {
visibleLabel.setText("true");
}
@Override
public void componentHidden(ComponentEvent componentEvent) {
visibleLabel.setText("false");
}
});
ActiveWindowChecker awcDeamon = new ActiveWindowChecker(q);
awcDeamon.setDaemon(true);
awcDeamon.start();
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
WinDef.RECT rect = null;
try {
rect = q.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (this.isActive()) {
System.out.println("action");
} else {
//System.out.println("rect = " + (rect != null ? rect : ""));
//System.out.println("frame = [(" + (int)this.getLocation().getX() + "," + (int)this.getLocation().getY() + ") (" + this.getSize().width + "," + this.getSize().height + ")]");
// x and y windows to compare top left point
int rxTop = rect == null ? 0: rect.left;
int ryTop = rect == null ? 0:rect.top;
int fxTop = (int) this.getLocation().getX();
int fyTop = (int) this.getLocation().getY();
// bottom right points
int rxBottom = rect == null ? 0: rect.right;
int ryBottom = rect == null ? 0: rect.bottom;
int fxBottom = fxTop + this.getSize().width;
int fyBottom = fyTop + this.getSize().height;
if ((rxTop >= fxTop || ryTop >= fyTop) || (rxBottom <= fxBottom || ryBottom <= fyBottom))
{
System.out.println("Not covered by active window.");
}
else{
System.out.println("Covered by active window.");
}
}
}
/**
* The entry point of application.
*
* @param args the input arguments
*/
public static void main(String... args) {
if (!System.getProperty("os.name").contains("Windows")) {
System.err.println("ERROR: Only implemented on Windows");
System.exit(1);
}
java.awt.EventQueue.invokeLater(() -> new App().setVisible(true));
}
}
我的工人班:
package com.sauliuxx.inc.workers;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import java.util.concurrent.BlockingQueue;
/**
* The type Active window checker.
*/
public class ActiveWindowChecker extends Thread {
private static final int MAX_TITLE_LENGTH = 1024;
private final BlockingQueue<WinDef.RECT> queue;
/**
* Instantiates a new Active window checker.
*
* @param q the q
*/
public ActiveWindowChecker(BlockingQueue<WinDef.RECT> q) {
this.queue = q;
}
@Override
public void run() {
Exception ex = null;
while (ex == null) {
char[] buffer = new char[MAX_TITLE_LENGTH * 2];
WinDef.HWND hwnd = User32.INSTANCE.GetForegroundWindow();
User32.INSTANCE.GetWindowText(hwnd, buffer, MAX_TITLE_LENGTH);
System.out.println("Active window title: " + Native.toString(buffer));
WinDef.RECT rect = new WinDef.RECT();
User32.INSTANCE.GetWindowRect(hwnd, rect);
try {
queue.put(rect);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
ex = e;
}
}
}
}
以上是关于是否可以检测窗口遮挡的主要内容,如果未能解决你的问题,请参考以下文章
Python代码阅读(第13篇):检测列表中的元素是否都一样
Unity判断鼠标是否在ui的Recttransform内的源码