You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Java的JFrame在Windows桌面预览(Desktop Peek)中不被隐藏?

可以实现,核心是调用Windows DWM(桌面窗口管理器)API设置窗口属性,让其在Desktop Peek时保持显示,用JNA就能完成,无需JNI。

核心原理

Windows的Desktop Peek由DWM控制,通过设置窗口的DWMWA_EXCLUDED_FROM_PEEK属性,可将窗口排除在Peek预览之外——也就是Peek触发时窗口不会被隐藏,Rainmeter正是基于这个机制实现的效果。

实现步骤(JNA方式)

  1. 引入JNA依赖
    若使用Maven,添加以下依赖:

    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>5.13.0</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna-platform</artifactId>
        <version>5.13.0</version>
    </dependency>
    
  2. 调用DWM API设置窗口属性
    定义DWM接口、获取Java窗口句柄,再调用DwmSetWindowAttribute完成设置:

    import com.sun.jna.Native;
    import com.sun.jna.platform.win32.WinDef;
    import com.sun.jna.platform.win32.WinNT;
    import com.sun.jna.win32.StdCallLibrary;
    import javax.swing.JFrame;
    
    public class PeekExcludeDemo {
        // 定义DWM API接口
        public interface DwmApi extends StdCallLibrary {
            DwmApi INSTANCE = Native.load("dwmapi", DwmApi.class);
    
            int DWMWA_EXCLUDED_FROM_PEEK = 11;
    
            // DwmSetWindowAttribute函数签名
            WinNT.HRESULT DwmSetWindowAttribute(WinDef.HWND hwnd, int dwAttribute,
                                               int[] pvAttribute, int cbAttribute);
        }
    
        public static void main(String[] args) {
            // 创建示例Swing窗口
            JFrame frame = new JFrame("Peek-resistant Window");
            frame.setSize(300, 200);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
    
            // 获取窗口底层句柄(HWND)
            WinDef.HWND hwnd = new WinDef.HWND(Native.getComponentPointer(frame));
    
            // 设置窗口排除在Peek之外:1=开启排除,0=恢复默认
            int[] excludeFlag = {1};
            WinNT.HRESULT result = DwmApi.INSTANCE.DwmSetWindowAttribute(
                    hwnd, DwmApi.DWMWA_EXCLUDED_FROM_PEEK, excludeFlag, 4);
    
            if (result.intValue() != 0) {
                System.err.println("设置失败,错误码: " + result.intValue());
            } else {
                System.out.println("窗口已设置为Peek时不隐藏");
            }
        }
    }
    

关键说明

  • 窗口句柄获取:Native.getComponentPointer(frame)直接获取Swing组件的底层HWND,比通过窗口标题查找更可靠,避免标题重复问题。
  • 属性值说明:DWMWA_EXCLUDED_FROM_PEEK的常量值为11,传入{1}启用排除,{0}则取消该设置。
  • 兼容性:该API仅支持Windows Vista及以上版本,若系统不支持DWM,调用会返回错误码。

JNI替代思路

如果一定要用JNI,本质是编写C代码调用DwmSetWindowAttribute,再通过JNI桥接让Java调用,但JNA已经封装了大部分Windows API,无需手动编写C代码,效率更高。

内容的提问来源于stack exchange,提问作者user17820402

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:57:12