我正在创建一个脚本,当按下组合键时,它将最小化当前活动窗口并移至下一个窗口。然后,当按下组合键时,展开最后一个最小化的窗口。
最小化活动窗口后,将焦点传递到下一个窗口(如果有)时存在问题。
在 ShowWindow 文档中写为“SW_MINIMIZE 6 最小化指定窗口并激活 Z 顺序中的下一个顶级窗口。”,但由于某种原因这对我不起作用。
User32.java
import jnr.ffi.LibraryLoader;
import jnr.ffi.Pointer;
import jnr.ffi.annotations.Delegate;
import jnr.ffi.types.u_int32_t;
public interface User32 {
User32 INSTANCE = LibraryLoader.create(User32.class).load("user32");
@u_int32_t
long GetForegroundWindow();
boolean SetForegroundWindow(@u_int32_t long hWnd);
boolean ShowWindow(@u_int32_t long hWnd, @u_int32_t long nCmdShow);
boolean IsIconic(@u_int32_t long hWnd);
boolean IsWindowVisible(@u_int32_t long hwnd);
void keybd_event(byte bVk, byte bScan, @u_int32_t int dwFlags,
int dwExtraInfo);
interface WinEnumProc {
@Delegate
boolean apply(@u_int32_t long hwnd, Pointer data);
}
boolean EnumWindows(WinEnumProc lpEnumFunc, Pointer lParam);
}
WindowManager.java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
public class WindowManager {
private static final Logger log = LogManager.getLogger(WindowManager.class.getName());
private static final int SW_MINIMIZE = 6;
private static final int SW_RESTORE = 9;
private static long lastWindow = 0;
public static void winMinimize() {
long activeWin = User32.INSTANCE.GetForegroundWindow();
log.info("Active window: {}", activeWin);
if (activeWin != 0) {
List<Long> windows = new ArrayList<>();
User32.INSTANCE.EnumWindows((hwnd, data) -> {
if (User32.INSTANCE.IsWindowVisible(hwnd)) {
windows.add(hwnd);
}
return true;
}, null);
lastWindow = activeWin;
User32.INSTANCE.ShowWindow(activeWin, SW_MINIMIZE);
int activeWinIndex = windows.indexOf(activeWin);
if (activeWinIndex != -1 && activeWinIndex + 1 < windows.size()) {
long nextWin = windows.get(activeWinIndex + 1);
log.info("Next win: {}", windows.get(activeWinIndex + 1));
// User32.INSTANCE.keybd_event((byte) 0xA4, (byte) 0x45, 0x2, 0);
User32.INSTANCE.SetForegroundWindow(nextWin);
}
log.info("Focus: {}", User32.INSTANCE.GetForegroundWindow());
}
}
public static void winRestore() {
if (lastWindow != 0 && User32.INSTANCE.IsIconic(lastWindow)) {
User32.INSTANCE.ShowWindow(lastWindow, SW_RESTORE);
User32.INSTANCE.SetForegroundWindow(lastWindow);
lastWindow = 0;
}
}
}
我创建了一个最大化窗口列表
windows
,从中获取下一个最大化窗口并尝试为其调用SetForegroundWindow
。该窗口开始闪烁,但焦点仍未转移。
我还找到了一个模拟按 Alt 键的解决方案,
User32.INSTANCE.keybd_event((byte) 0xA4, (byte) 0x45, 0x2, 0)
,但我觉得这很奇怪。我希望获得与鼠标单击最小化窗口按钮时相同的行为。
我已经阅读了关于 SetForegroundWindow 的文档,也许问题出在线程中,但我不明白我需要做什么来解决它。
在 @IInspectable 和 @Starship 的建议之后,我阅读了有关 RegisterHotKey 和 AttachThreadInput 的内容。 这确实解决了我的问题。我还找到了使用 RegisterHotKey 的 jintellitype 库。