29

As we all know, if the icon for a wpf window is undefined then the default icon is displayed. I want to display a window without any icon in the title bar. I realise that I could use a blank image, however this would cause the text in the title bar to be offset to the right.

Does anyone know of a way to completely remove the icon?

(I tried searching for a similar question but couldn't find anything.)

Michael Arnell
  • 1,008
  • 1
  • 9
  • 16

7 Answers7

33

Simple, add this code to your window:

[DllImport("user32.dll")]
static extern uint GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

private const int GWL_STYLE = -16;

private const uint WS_SYSMENU = 0x80000;

protected override void OnSourceInitialized(EventArgs e)
{
    IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    SetWindowLong(hwnd, GWL_STYLE,
        GetWindowLong(hwnd, GWL_STYLE) & (0xFFFFFFFF ^ WS_SYSMENU));

    base.OnSourceInitialized(e);
}
Nir
  • 29,306
  • 10
  • 67
  • 103
  • Had to modify a bit based on code in "How to hide close button in wpf window?", but this did work! – Michael Arnell Oct 13 '09 at 11:52
  • 17
    This seems to get rid of the "close" button as well which isn't always desired. – Keith Hill Aug 18 '10 at 19:36
  • @MichaelArnell how were you able to put back the close button? – TheFrustratedProgrammer Feb 21 '13 at 02:26
  • @Frustrated I didn't need the close button, so wasn't worried about it. You would have to look at the Win32 API documentation for SetWindowLong (see http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633591(v=vs.85).aspx) to figure out which values you would need for GWL_STYLE (see http://msdn.microsoft.com/en-gb/library/windows/desktop/ms632600(v=vs.85).aspx). – Michael Arnell Feb 21 '13 at 14:07
  • But its not worked for me..Is there anything i need to do much more? @Nir – User6667769 Jun 24 '17 at 10:36
  • Yes, you also must remove ICON_BIG and ICON_SMALL using: SendMessage(hwnd, WM_SETICON, ICON_SMALL, IntPtr.Zero); SendMessage(hwnd, WM_SETICON, ICON_BIG, IntPtr.Zero); Follow the above answer but also add these two statements and it will work. ICON_BIG is 0 and ICON_SMALL is 1. The third parameter of SendMessage() should be int, if you have it as IntPtr fix it. – Chris Bordeman Dec 08 '18 at 16:50
17

While not exactly a proper solution, you could try one of the following things:

  1. Setting the WindowStyle-Property to ToolWindow will make the Icon disappear, but the title bar (obviously) will be smaller.

  2. Write a ControlTemplate for the whole Window. Depending on if the Window has to look like a "real" Window, there'd be much effort into trying to recreate the default Style in the Template.

Andrej
  • 981
  • 8
  • 17
  • I think the WPF'ed parts of the Expression suite may draw everything (including title bars) themselves to allow for such things. Still, looking and behaving natively is a very nice thing to have for the user, imho. – Joey Oct 12 '09 at 10:18
  • +1 The "ToolWindow" WindowStyle is exactly what I was looking for! – ewall Dec 29 '09 at 20:12
11

I know this is answered, however Dan Rigsby's blog has an article that shows how to do this without hiding the minimize/maximize boxes.

I found this was frustrating me as I was using the articles (here and here but it kept hiding all the buttons when the sysmenu was hidden, to help I created this helper which as shown above call in OnSourceInitialized.

public static class WpfWindowHelper {

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

    public const int GWL_EXSTYLE = -20;
    public const int WS_EX_DLGMODALFRAME = 0x0001;
    public const int SWP_NOSIZE = 0x0001;
    public const int SWP_NOMOVE = 0x0002;
    public const int SWP_NOZORDER = 0x0004;
    public const int SWP_FRAMECHANGED = 0x0020;
    public const int GWL_STYLE = -16;
    public const int WS_MAXIMIZEBOX = 0x00010000;
    public const int WS_MINIMIZEBOX = 0x00020000;
    public const int WS_SYSMENU = 0x00080000;

    public static void HideSysMenu(this Window w) {
        IntPtr hwnd = new WindowInteropHelper(w).Handle;
        int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
        SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);
        SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    }

    public static void HideMinimizeBox(this Window w) {
        IntPtr hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE,
            GetWindowLong(hwnd, GWL_STYLE) & ~(WS_MINIMIZEBOX));
    }

    public static void HideMaximizeBox(this Window w) {
        IntPtr hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE,
            GetWindowLong(hwnd, GWL_STYLE) & ~(WS_MAXIMIZEBOX));
    }

    public static void HideMinimizeAndMaximizeBoxes(this Window w) {
        IntPtr hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE,
            GetWindowLong(hwnd, GWL_STYLE) & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX));
    }

}
Brett Ryan
  • 26,937
  • 30
  • 128
  • 163
  • 1
    HideSysMenu (WS_EX_DLGMODALFRAME) does the thing! Hide the icon, but leaving the close button intact. – HelloSam Sep 14 '12 at 05:34
  • 2
    Sorry, it doesn't do a thing. Both icon and close button are still there. I want only the icon to disappear, according to Microsoft's own UI guidelines for dialog windows. – ygoe Sep 02 '13 at 19:31
  • It doesn't work because you're missing two statements (need your code plus the following): SendMessage(hwnd, WM_SETICON, ICON_SMALL, IntPtr.Zero); SendMessage(hwnd, WM_SETICON, ICON_BIG, IntPtr.Zero); – Chris Bordeman Dec 08 '18 at 16:58
10

No, this doesn't seem to be possible. Quoting from the documentation of the Icon property (emphasis mine):

A WPF window always displays an icon. When one is not provided by setting Icon, WPF chooses an icon to display based on the following rules:

  1. Use the assembly icon, if specified.
  2. If the assembly icon is not specified, use the default Microsoft Windows icon.

If you use Icon to specify a custom window icon, you can restore the default application icon by setting Icon to null.

So, apparently a completely transparent icon seems to be your best bet here. Or perhaps hack around all this by using Windows API functions to set the appropriate style on the window. But this may interfere with WPF's window management.

Community
  • 1
  • 1
Joey
  • 344,408
  • 85
  • 689
  • 683
6

You can use an empty png image and convert it to icon and set it as icon for your window!!!

enter image description here

mehdi
  • 645
  • 1
  • 9
  • 9
0

Add the following code to the main class of your Window to remove the maximize and minimize buttons, and hide the icon.

private const uint WS_MINIMIZEBOX = 0x00020000;
private const uint WS_MAXIMIZEBOX = 0x00010000;
private const int GWL_STYLE = -16;
private const int GWL_EXSTYLE = -20;
private const int SWP_NOSIZE = 0x0001;
private const int SWP_NOMOVE = 0x0002;
private const int SWP_NOZORDER = 0x0004;
private const int SWP_FRAMECHANGED = 0x0020;
private const int WM_SYSCOMMAND = 0x0112;
private const int WM_SETICON = 0x0080;
private const int WS_EX_DLGMODALFRAME = 0x0001;

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

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

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

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

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    
    IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    uint styles = GetWindowLong(hwnd, GWL_STYLE);

    // Remove the maximize and minimize buttons
    styles &= 0xFFFFFFFF ^ (WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
    SetWindowLong(hwnd, GWL_STYLE, styles);
    
    // Change to dialog modal - necessary for the final step to work!
    styles = GetWindowLong(hwnd, GWL_EXSTYLE);
    styles |= WS_EX_DLGMODALFRAME;
    SetWindowLong(hwnd, GWL_EXSTYLE, styles);

    SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    ((HwndSource)PresentationSource.FromVisual(this)).AddHook(HelpButtonHook);

    // Remove the icon
    SendMessage(hwnd, WM_SETICON, new IntPtr(1), IntPtr.Zero);
    SendMessage(hwnd, WM_SETICON, IntPtr.Zero, IntPtr.Zero);
}
AntikM
  • 636
  • 4
  • 13
  • 28
-3

My first suggestion would be don't do it. In WinForms you can use types of formborderstyles to create a dialog box that has no icon, but only because that is a Windows standard. Only forms with those specific border types should have no icon; it's what users expect.

Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220
  • 1
    Windows Forms also has a `ShowIcon` property. – Joey Oct 12 '09 at 10:11
  • 1
    Unfortunately, there appears to be no real distinction between windows and dialogs in WPF. – Michael Arnell Oct 12 '09 at 10:20
  • 4
    The [design guidelines for Windows error dialogs](https://msdn.microsoft.com/en-gb/library/windows/desktop/dn742471.aspx#icons) states otherwise: "_Modal error message dialogs don't have title bar icons_" – g t Nov 05 '15 at 09:20