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

7

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.)

Truckle answered 12/10, 2009 at 10:2 Comment(0)
R
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);
}
Riobard answered 13/10, 2009 at 10:58 Comment(6)
Had to modify a bit based on code in "How to hide close button in wpf window?", but this did work!Truckle
This seems to get rid of the "close" button as well which isn't always desired.Change
@MichaelArnell how were you able to put back the close button?Wong
@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 msdn.microsoft.com/en-gb/library/windows/desktop/…) to figure out which values you would need for GWL_STYLE (see msdn.microsoft.com/en-gb/library/windows/desktop/…).Truckle
But its not worked for me..Is there anything i need to do much more? @RiobardBlat
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.Zachery
M
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.

Monophagous answered 12/10, 2009 at 10:15 Comment(2)
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.Wort
+1 The "ToolWindow" WindowStyle is exactly what I was looking for!Savannasavannah
C
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));
    }

}
Costume answered 16/5, 2011 at 22:37 Comment(3)
HideSysMenu (WS_EX_DLGMODALFRAME) does the thing! Hide the icon, but leaving the close button intact.Meimeibers
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.Bidwell
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);Zachery
W
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.

Wort answered 12/10, 2009 at 10:9 Comment(0)
F
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

Faerie answered 9/2, 2015 at 8:32 Comment(3)
This is the simplest and best solution. +1Riddell
The image still takes up space in the window title thoughSellers
If your window had a title, you'd see why this is not a good solution.Zachery
M
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);
}
Millen answered 7/5, 2021 at 20:15 Comment(0)
K
-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.

Kolk answered 12/10, 2009 at 10:10 Comment(3)
Windows Forms also has a ShowIcon property.Wort
Unfortunately, there appears to be no real distinction between windows and dialogs in WPF.Truckle
The design guidelines for Windows error dialogs states otherwise: "Modal error message dialogs don't have title bar icons"Meddlesome

© 2022 - 2024 — McMap. All rights reserved.