java windows 取所有任务_Java-Windows:如何获取所有可见窗口的列表?

要枚举顶级窗口,应该使用EnumWindows而不是GetTopWindow / GetNextWindow,因为EnumWindows返回窗口状态的一致视图。 当窗口在迭代过程中更改z顺序时,您可能会面临获得不一致的信息(例如,有关已删除窗口的报告)或使用GetTopWindow / GetNextWindow导致无限循环的风险。

EnumWindows使用回调。 在回调的每次调用中,您都会获得一个窗口句柄。 可以通过将该句柄传递给GetWindowRect来获取窗口的屏幕坐标。 您的回调将以z顺序构建窗口位置的列表。

您可以使用轮询,然后重复构建窗口列表。 或者,您可以设置一个CBTHook来接收窗口更改的通知。 并非所有的CBT通知都会导致顶级窗口的顺序,位置或可见性发生变化,因此明智的做法是重新运行EnmWindows以按z顺序构建新的窗口位置列表,并将其与上一个列表进行比较,然后再进一步处理该列表, 以便仅在发生实际更改时才进行进一步处理。

请注意,使用钩子不能将32位和64位混合使用。 如果您运行的是32位应用程序,则将收到32位进程的通知。 同样适用于64位。 因此,如果要在64位计算机上监视整个系统,则似乎有必要运行两个应用程序。 我的推理来自阅读以下内容:

SetWindowsHookEx可用于注入 一个DLL进入另一个进程。 32位 DLL无法注入64位 进程,并且不能将64位DLL 注入到32位进程中。 如果 应用程序需要使用挂钩 在其他过程中,这是必需的 一个32位应用程序调用 SetWindowsHookEx注入32位 DLL转换为32位进程,并且 64位应用程序调用 SetWindowsHookEx注入64位 DLL转换为64位进程。 32位 和64位DLL必须具有不同的 名称。 (从SetWindowsHookEx api页面。)

在用Java实现此过程时,您可能需要看一下JNA-它使对本机库的写访问更加简单(在Java中调用代码),并且不需要您自己的本机JNI DLL。

编辑:您问它是多少代码和要写多长时间。 这是java中的代码

import com.sun.jna.Native;

import com.sun.jna.Structure;

import com.sun.jna.win32.StdCallLibrary;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

public class Main {

public static void main(String[] args) {

Main m = new Main();

final List inflList = new ArrayList();

final List order = new ArrayList();

int top = User32.instance.GetTopWindow(0);

while (top != 0) {

order.add(top);

top = User32.instance.GetWindow(top, User32.GW_HWNDNEXT);

}

User32.instance.EnumWindows(new WndEnumProc() {

public boolean callback(int hWnd, int lParam) {

if (User32.instance.IsWindowVisible(hWnd)) {

RECT r = new RECT();

User32.instance.GetWindowRect(hWnd, r);

if (r.left > -32000) { // If it's not minimized

byte[] buffer = new byte[1024];

User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);

String title = Native.toString(buffer);

inflList.add(new WindowInfo(hWnd, r, title));

}

}

return true;

}

}, 0);

Collections.sort(inflList, new Comparator() {

public int compare(WindowInfo o1, WindowInfo o2) {

return order.indexOf(o1.hwnd)-order.indexOf(o2.hwnd);

}

});

for (WindowInfo w : inflList) {

System.out.println(w);

}

}

public static interface WndEnumProc extends StdCallLibrary.StdCallCallback {

boolean callback(int hWnd, int lParam);

}

public static interface User32 extends StdCallLibrary {

final User32 instance = (User32) Native.loadLibrary ("user32", User32.class);

final int GW_HWNDNEXT = 2;

boolean EnumWindows(WndEnumProc wndenumproc, int lParam);

boolean IsWindowVisible(int hWnd);

int GetWindowRect(int hWnd, RECT r);

void GetWindowTextA(int hWnd, byte[] buffer, int buflen);

int GetTopWindow(int hWnd);

int GetWindow(int hWnd, int flag);

}

public static class RECT extends Structure {

public int left, top, right, bottom;

}

public static class WindowInfo {

public final int hwnd;

public final RECT rect;

public final String title;

public WindowInfo(int hwnd, RECT rect, String title) {

this.hwnd = hwnd;

this.rect = rect;

this.title = title;

}

public String toString() {

return String.format("(%d,%d)-(%d,%d) : \"%s\"",

rect.left, rect.top,

rect.right, rect.bottom,

title);

}

}

}

我制作了大多数相关类和接口内部类,以使示例紧凑且可粘贴以立即进行编译。 在实际的实现中,它们将是常规的顶级类。 命令行应用程序将打印出可见窗口及其位置。 我在32位jvm和64位上都运行了它,并且得到了相同的结果。

EDIT2:更新了代码以包括z顺序。 它确实使用GetNextWindow。 在生产应用程序中,您可能应该为下一个和上一个值两次调用GetNextWindow,并检查它们是否一致并且是有效的窗口句柄。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值