隐藏的 JDialog 在 Windows 10 任务栏速览预览中仍然可见

Hidden JDialog still visible in Windows 10 taskbar peek preview

配置为HIDE_ON_CLOSEJDialog关闭后不可见。但它在 Windows 任务栏的速览预览中仍然可见。只有在主要 window 最小化并再次最大化后才能更正预览。当然可以处理对话框而不是隐藏它,但这不是我的目标。

代码示例:

    public static void main( String[] args ) throws Exception {
        JFrame frame = new JFrame();
        frame.setTitle( "frame" );
        frame.setSize( 700, 700 );
        frame.setVisible( true );
        frame.setDefaultCloseOperation( JDialog.EXIT_ON_CLOSE );
    
        JDialog d = new JDialog( frame ); // modeless dialog
        d.setTitle( "dialog" );
        d.setSize( 300, 300 );
        d.setDefaultCloseOperation( JDialog.HIDE_ON_CLOSE );
        d.setVisible( true );
    }

请尝试直接在对话框上设置 WS_EX_TOOLWINDOW 样式,然后再隐藏它。然后立即删除它(这样它就不会影响后续节目的渲染)。

工具栏 windows 不允许出现在任务栏上,因此无法预览。这是一个 hack,但它对我在 Windows 11.

中的类似问题有用

这是在 Windows 11 上对我有用的代码。我能够使用 JDK17 在 Windows 11 上重现错误。

你需要https://github.com/java-native-access/jnajna.jarplatform.jar)。没有它,我找不到设置 win32 window 样式的方法。

javac -cp .;./jna.jar;./platform.jar jdtest.java

import javax.swing.JFrame;
import javax.swing.JDialog;
import java.awt.event.*;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinUser;
public class jdtest
{
    
    public static int WS_EX_TOOLWINDOW = 0x00000080;
    public static void changeStyle(HWND hwnd, boolean hiding) {
        int exStyle = User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
        if (hiding) {
            User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, exStyle | WS_EX_TOOLWINDOW);
        } else {
            User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, exStyle & ~WS_EX_TOOLWINDOW);
        }
    }
    
    private static HWND getHWnd(JDialog d) {
        HWND hwnd = new HWND();
        hwnd.setPointer(Native.getWindowPointer(d));
        return hwnd;
    }

    public static void main( String[] args ) throws Exception {
        JFrame frame = new JFrame();
        frame.setTitle( "frame" );
        frame.setSize( 700, 700 );
        frame.setVisible( true );
        frame.setDefaultCloseOperation( JDialog.EXIT_ON_CLOSE );

        JDialog d = new JDialog( frame ); // modeless dialog
        d.setTitle( "dialog" );
        d.setSize( 300, 300 );
        d.setDefaultCloseOperation( JDialog.HIDE_ON_CLOSE );

        d.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                changeStyle(getHWnd(d), true);
            }
        });
        d.addWindowListener(new WindowAdapter() {
            public void windowOpening(WindowEvent e) {
                changeStyle(getHWnd(d), false);
            }
        });

        d.setVisible( true );
    }
}