23

I am able to remove the window icon from WPF window using WinApi's, however I get the icon again in the application window when I run just the executable of the WPF project.

How do I remove the icon?

Kyle Rosendo
  • 25,001
  • 7
  • 80
  • 118
shraddha
  • 853
  • 5
  • 9
  • 20

6 Answers6

26

From WPFTutorial:

How to remove the icon of a WPF window

alt text

Unfortunately WPF does not provide any function to remove the icon of a window. One solution could be setting the icon to a transparent icon. But this way the extra space between the window border and title remains.

The better approach is to use a function provided by the Win32 API to remove the icon.

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

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

A helper class used to remove the icon.

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);
    }
}
Vadim Ovchinnikov
  • 13,327
  • 5
  • 62
  • 90
Michal Ciechan
  • 13,492
  • 11
  • 76
  • 118
  • 4
    the same code i have used it does not remove the icon from the window when i run the project just using the exe....where m not using the visual studio to run the project – shraddha Feb 26 '10 at 12:19
  • @LnDCobra: Good answer, +1. Note that you could easily implement this as an attached property, which would enable removing the icon declaratively, in XAML – Thomas Levesque Feb 26 '10 at 12:41
  • itz getting removed my problem is its attaching all together new icon for exe file – shraddha Feb 26 '10 at 13:14
  • this helped me alot...n i just wanted to share some info about wpf window icons... http://msdn.microsoft.com/en-us/library/system.windows.window.icon.aspx – shraddha Mar 02 '10 at 18:53
  • I have found that this soulution does not work if Aero is disabled in Windows 7 or if the application is run on Windows XP (and Windows 2003 I would guess). – jmatthias Apr 03 '12 at 20:33
  • 4
    @jmatthias Yes. The fix is to add this line at the bottom: SendMessage(hwnd, WM_SETICON, IntPtr.Zero, IntPtr.Zero); – Mike Blandford Oct 12 '12 at 17:03
  • 1
    You may wish to add `SWP_NOACTIVATE(0x0010)` flag to prevent the window from being activated with `SetWindowPos` function. – ghord Nov 25 '13 at 11:49
22

Just add this WindowStyle="ToolWindow" to your window properties.

Matiullah Karimi
  • 1,234
  • 1
  • 15
  • 17
15

I have modified the sample from 'LnDCobra' so it can be used as an attached property (as 'Thomas' suggested:

<Window 
        ...
        xmlns:i="clr-namespace:namespace-to-WindowEx"
        i:WindowEx.ShowIcon = "false"
        ...
>

Implementation of WindowEx:

public class WindowEx
  {
    private const int GwlExstyle = -20;
    private const int SwpFramechanged = 0x0020;
    private const int SwpNomove = 0x0002;
    private const int SwpNosize = 0x0001;
    private const int SwpNozorder = 0x0004;
    private const int WsExDlgmodalframe = 0x0001;

    public static readonly DependencyProperty ShowIconProperty =
      DependencyProperty.RegisterAttached(
        "ShowIcon",
        typeof (bool),
        typeof (WindowEx),
        new FrameworkPropertyMetadata(true, new PropertyChangedCallback((d, e) => RemoveIcon((Window) d))));


    public static Boolean GetShowIcon(UIElement element)
    {
      return (Boolean) element.GetValue(ShowIconProperty);
    }

    public static void RemoveIcon(Window window)
    {
      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, GwlExstyle);
        SetWindowLong(hwnd, GwlExstyle, extendedStyle | WsExDlgmodalframe);

        // Update the window's non-client area to reflect the changes
        SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SwpNomove |
          SwpNosize | SwpNozorder | SwpFramechanged);
      };
    }

    public static void SetShowIcon(UIElement element, Boolean value)
    {
      element.SetValue(ShowIconProperty, value);
    }

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

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

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

    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
      int x, int y, int width, int height, uint flags);
  }
}
Gregor Slavec
  • 4,814
  • 1
  • 26
  • 24
  • 5
    For me this works fine in debug mode but not if I run it outside the debug environment. – Christoph Meißner Jan 25 '12 at 15:46
  • the accepted answer didn't work in .NET4.5 while your answer worked for me. thanks! worked both from visual studio in debug mode as well as by running the exe from windows explorer. – sudarsanyes Jul 08 '14 at 07:19
  • 1
    This answer worked for me in .NET4.5 when I combined it with this answer: http://stackoverflow.com/questions/18580430/hide-the-icon-from-a-wpf-window. Also XAML designer complained that it cannot cast WindowsInstance to Window, so I had to rewrite it a bit and remove direct cast to window: `PropertyChangedCallback((d, e) => RemoveIcon((Window) d)`; – username Jan 26 '17 at 11:59
10

Here a simple and pure XAML solution:

<Window x:Class="...">

    <Window.Icon>
        <DrawingImage />
    </Window.Icon>

    ...

</Window>
Orace
  • 7,822
  • 30
  • 45
  • 5
    This should be the accepted answer. The title is of course pushed by the empty icon but that is a small price to pay. I just hate messing with windows DLL just to remove an icon! – Nandostyle Aug 14 '20 at 16:58
  • 1
    This appears to make the taskbar icon blank – Vultuxe Aug 24 '21 at 15:26
7

I just use very small transparent image as an icon (1x1 px) for WPF window.

Ilya Solovyev
  • 313
  • 1
  • 3
  • 8
2

Create a transparent 1 by 1 icon and replace it with a standard one

Icon = BitmapSource.Create(1, 1, 0, 0, PixelFormats.Bgra32, null, new byte[4], 4);
Konstantin S.
  • 1,307
  • 14
  • 19