隐藏WPF窗口中的图标

时间:2013-09-02 20:35:08

标签: wpf window icons

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

是否有人能够在今天和指定的环境中使用仍然有效的解决方案?

3 个答案:

答案 0 :(得分:24)

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

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属性,它将无效,但我猜你没有这样做,如果你没有想要一个图标出现。

答案 1 :(得分:10)

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

答案 2 :(得分:1)

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

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