【问题标题】:Hide the icon from a WPF window从 WPF 窗口隐藏图标
【发布时间】:2013-09-05 23:43:21
【问题描述】:

我知道有很多关于隐藏或删除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 函数或物理之上。

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

【问题讨论】:

标签: wpf window icons


【解决方案1】:

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

Removing Icon from a WPF window

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

How to remove the icon of a WPF window

How to remove Icon from window titlebar

How to hide window icon in WPF


您关于这不适用于大型应用程序的最后评论让我想知道。因此,我随后将代码添加到大型应用程序中,它再次运行良好。但是,我继续对此进行测试,而您必须在您的应用程序中使用RibbonWindow,因为当我使用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 属性,它将不起作用,但我猜如果您不想要图标。

【讨论】:

  • 抱歉,我都看过了,但没有任何效果。从您的回答中,我看到您没有阅读我的问题,尤其是没有验证这些建议是否确实有效。
  • 奇怪。那为什么它在我的情况下不起作用?也许我应该添加另一个重要要求:在测试用例之外工作,在具有非空窗口且存在多个窗口的实际应用程序中。如果这有帮助的话。
  • 也许 Sheridan 应该编辑第一句话 - 对于未来使用 Google 的读者来说,粗鲁是必要的。
  • 我发现了一个不同之处:只要我的 .exe 文件包含图标资源,该图标就会在窗口中使用。如果我将项目设置保留为“默认图标”并且不将其他非托管图标添加到我的 .exe 文件中,那么它可以工作。但只要有一个图标,它就会显示出来。
  • @Sheridan “如果您只是将标题中的单词放入搜索引擎,而不是像我刚才所做的那样,那么您会找到比这些更多的结果。” i> - 虽然当时可能有用,但我觉得它不再相关。我在 Google 中使用短语 "hide icon for wpf window" first match 进行了搜索。考虑删除那个第一句
【解决方案2】:

从具有图标的 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)

【讨论】:

  • 谢谢,这确实有效。似乎需要避免使用 .exe 图标资源。请参阅我对其他答案的评论。
  • 在 MPF 项目系统中使用时,上述代码删除了默认进程图标(VS2013),但在其位置留下了通用图标
  • 非常感谢!我遇到了问题,在启动带有调试器的应用程序时,图标被正确删除,但在没有调试器的情况下启动发布版本时却没有。您的解决方案解决了这个问题!
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多