8

我知道有很多关于隐藏或删除WPF窗口左上角图标的问题,系统菜单所在的地方。我已经尝试了很多,但没有一个有效。以下是我的要求:

  • 图标消失并且不占用任何空白空间(即没有透明图标)
  • 窗口标题直接从窗口的左边缘开始
  • 右上角的关闭按钮仍然存在并且有效
  • 如果启用,最小化/最大化按钮仍然存在(可选,未测试)
  • 无需自定义绘制整个窗框
  • 在启用 Aero Glass 的 Windows 7 上工作(Windows 8 有人吗?)
  • 适用于 32 位和 64 位 Windows(x86 和 x64 构建)
  • 适用于 WPF .NET 4.0
  • 不在像 Visual Studio 这样的调试器中工作(如果它也在调试器中工作会很好)
  • 也应该在 Windows XP 上工作(可选)

可用的答案基本上是使用Windows API函数GetWindowLongSetWindowLong有时还SetWindowPos添加扩展窗口样式WS_EX_DLGMODALFRAME和调用SWP_FRAMECHANGED。有时,也会设置或取消设置其他样式。

不幸的是,这些都不起作用。我可以没有没有关闭按钮的图标,或者两者都在那里。但同样值得注意的是,所有这些内容都来自 2010 年或更早。它似乎是针对早期的 .NET 或 Windows 版本而失败的。

我已经将系统对话框的窗口样式(来自资源管理器)和我的 WPF 窗口与 Microsoft Spy++(包含在 Visual Studio 中)进行了比较。但我可以尝试将所有标志设置为相同,图标不会消失。这就像黑魔法,凌驾于所有其他 API 函数或物理之上。

有没有人有一个在今天和指定环境中仍然有效的解决方案?

4

3 回答 3

23

如果您只是将标题中的单词放入搜索引擎,而不是像我刚才所做的那样,那么您会发现比这些更多的结果。您可以在以下内容中找到您的答案:

从 WPF 窗口中删除图标

是否可以在标题栏中显示没有图标的 wpf 窗口?

如何删除 WPF 窗口的图标

如何从窗口标题栏中删除图标

如何在WPF中隐藏窗口图标


您关于这不适用于大型应用程序的最后评论让我想知道。因此,我随后将代码添加到大型应用程序中,它再次运行良好。但是,我继续对此进行测试,并且您必须在您的应用程序中使用 a RibbonWindow,因为当我使用 a 在大型应用程序上测试此代码时,RibbonWindow该代码不起作用

如果您使用的是普通Window代码,请尝试使用此代码(来自@MichalCiechan 对第一个链接帖子的回答):

首先添加这个类:

public static class IconHelper
{
    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hwnd, int index);

    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);

    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, 
int y, int width, int height, uint flags);

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr 
lParam);

    const int GWL_EXSTYLE = -20;
    const int WS_EX_DLGMODALFRAME = 0x0001;
    const int SWP_NOSIZE = 0x0001;
    const int SWP_NOMOVE = 0x0002;
    const int SWP_NOZORDER = 0x0004;
    const int SWP_FRAMECHANGED = 0x0020;
    const uint WM_SETICON = 0x0080;

    public static void RemoveIcon(Window window)
    {
        // Get this window's handle
        IntPtr hwnd = new WindowInteropHelper(window).Handle;
        // Change the extended window style to not show a window icon
        int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
        SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);
        // Update the window's non-client area to reflect the changes
        SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | 
SWP_NOZORDER | SWP_FRAMECHANGED);
    }
}

然后将其添加到MainWindow.xaml.cs

protected override void OnSourceInitialized(EventArgs e)
{
    IconHelper.RemoveIcon(this);
}

哦...还有一件事要注意...如果您设置了属性,它将不起作用Window.Icon,但我猜如果您不希望出现图标,您还没有这样做。

于 2013-09-02T21:39:17.347 回答
13

从具有图标的 WPF 应用程序创建对话框窗口时,上述方法不起作用。但是,当添加以下两行时,图标会正确地从对话窗口中消失:

SendMessage(hwnd, WM_SETICON, new IntPtr(1), IntPtr.Zero);
SendMessage(hwnd, WM_SETICON, IntPtr.Zero, IntPtr.Zero);

(sa https://connect.microsoft.com/VisualStudio/feedback/details/745230/wpf-window-cannot-be-displayed-without-titlebar-icon

于 2014-08-05T13:04:59.937 回答
2

这是我在看到这个问题的不同解决方案后想到的:

    internal const int SWP_NOSIZE = 0x0001;
    internal const int SWP_NOMOVE = 0x0002;
    internal const int SWP_NOZORDER = 0x0004;
    internal const int SWP_FRAMECHANGED = 0x0020;
    internal const int GWL_EXSTYLE = -20;
    internal const int WS_EX_DLGMODALFRAME = 0x0001;

    [DllImport("user32.dll", SetLastError = true)]
    internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll")]
    internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    [DllImport("user32.dll")]
    internal static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);

    /// <summary>
    /// Hides icon for window.
    /// If this is called before InitializeComponent() then the icon will be completely removed from the title bar
    /// If this is called after InitializeComponent() then an empty image is used but there will be empty space between window border and title
    /// </summary>
    /// <param name="window">Window class</param>
    internal static void HideIcon(this Window window)
    {
        if (window.IsInitialized)
        {
            window.Icon = BitmapSource.Create(1, 1, 96, 96, PixelFormats.Bgra32, null, new byte[] {0, 0, 0, 0}, 4);
        }
        else
        {
            window.SourceInitialized += delegate
            {
                // Get this window's handle
                var hwnd = new WindowInteropHelper(window).Handle;

                // Change the extended window style to not show a window icon
                int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
                SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);

                // Update the window's non-client area to reflect the changes
                SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
            };
        }
    }

例子:

public partial class ExampleWindow : Window
{
    public ExampleWindow()
    {
        // Hides icon completely
        this.HideIcon();

        InitializeComponent();
    }
}
于 2015-09-21T01:27:35.983 回答