在 WPF 窗口中隐藏图标

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18580430/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:55:44  来源:igfitidea点击:

Hide the icon from a WPF window

wpfwindowicons

提问by ygoe

I know that there are many questions about hiding or removing the icon from the upper left corner of a WPF window, the place where the system menu is. I've tried many of them but none works. Here are my requirements:

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

  • The icon disappears and does not take any empty space (i. e. no transparent icon)
  • The window title starts directly at the left edge of the window
  • The close button in the upper right corner is still there and works
  • Minimise/maximise buttons are still there if enabled (optional, didn't test this)
  • No custom-drawing of the entire window frame
  • Works on Windows 7 with Aero Glass enabled (Windows 8 anybody?)
  • Works on 32 and 64 bit Windows (x86 and x64 build)
  • Works with WPF .NET 4.0
  • Works when not in a debugger like Visual Studio (would be nice if it also works in the debugger)
  • Should also work on Windows XP (optional)
  • 图标消失并且不占用任何空白空间(即没有透明图标)
  • 窗口标题直接从窗口的左边缘开始
  • 右上角的关闭按钮仍然存在并且有效
  • 如果启用,最小化/最大化按钮仍然存在(可选,未测试)
  • 没有自定义绘制整个窗框
  • 适用于启用 Aero Glass 的 Windows 7(Windows 8 任何人?)
  • 适用于 32 位和 64 位 Windows(x86 和 x64 版本)
  • 适用于 WPF .NET 4.0
  • 不在像 Visual Studio 这样的调试器中工作(如果它也能在调试器中工作,那就太好了)
  • 也应该在 Windows XP 上工作(可选)

The available answers basically use the Windows API functions GetWindowLong, SetWindowLongand sometimes also SetWindowPosto add the extended window style WS_EX_DLGMODALFRAMEand call SWP_FRAMECHANGED. Sometimes, other styles are also set or unset.

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

Unfortunately, none of this works at all. I can either have no icon with no close button, or both are still there. But it's also noticeable that all of that content is from 2010 or eariler. It seems it's targeted at earlier .NET or Windows versions and fails since.

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

I've already compared the window styles of system dialogs (from Explorer) and my WPF windows with Microsoft Spy++ (included in Visual Studio). But I can try to set all flags the same, the icon won't go away. It's like black magic that overrules every other API function or physics.

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

Does anybody have a solution that still works today and in the indicated environment?

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

回答by Sheridan

Ifyou had just put the words in your title into a search engine instead of here as I just did, then you would have found many more results than these. You can find your answer in the following:

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

Removing Icon from a WPF window

从 WPF 窗口中删除图标

Is it possible to display a wpf window without an icon in the title bar?

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

How to remove the icon of a WPF window

如何删除 WPF 窗口的图标

How to remove Icon from window titlebar

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

How to hide window icon in WPF

如何在WPF中隐藏窗口图标



Your last comment about this not working on large scale applications made me wonder. As such, I then added the code to a large scale application and once again it worked just fine. However, I continued to test this and you mustbe using a RibbonWindowin your application, because when I tested this code on a large scale application with a RibbonWindowthe code did notwork.

您关于这不适用于大型应用程序的最后评论让我感到奇怪。因此,我随后将代码添加到大型应用程序中,它再次运行得很好。但是,我继续测试这一点,你必须使用一个RibbonWindow在你的应用程序,因为当我与一个大规模应用测试此代码RibbonWindow的代码确实没有工作。

If you are using a normal Windowthen give this code a try (From @MichalCiechan's answer to the first linked post):

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

First add this class:

首先添加这个类:

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);
    }
}

Then add this to MainWindow.xaml.cs:

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

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

Oh... and one other thing to note... it won't work if you have set the Window.Iconproperty, but I'm guessing that you haven't done that if you don't want an icon to appear.

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

回答by o-toole-kit

The above does not work, when creating a dialog window from a WPF application having an icon. However, when adding the following two lines, the icon correctly vanishes from the dialog window:

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

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

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

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

回答by ub3rst4r

This is what I came up with after seeing different solutions to this question:

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

    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);
            };
        }
    }

Example:

例子:

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

        InitializeComponent();
    }
}