In general, you should have windows that show both a window icon and a system menu. Having a window icon helps the user determine where they click to get the system menu (the window icon) and where they double click to maximize/restore their window (the area not taken up by the window icon and the minimize, restore, maximize, and close buttons).

Still, there are scenarios where folks really really don't want to show the window icon. And System.Windows.Forms.Form has the ShowIcon property because folks really really don't want to show the window icon. This post is for them :)

By default, if you don't specify an icon for a WPF Window, WPF will show an icon anyway, as determined by the algorithm described here. To override this behavior, you can use a p/invoke your way to an icon-less lifestyle using code like the following:

<!-- MainWindow.xaml -->

<Window

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    x:Class="WPFWindowWithoutIcon.MainWindow"

    Title="&lt;-- No Icon Here!"

    Height="100" Width="225">

 

</Window>

// MainWindow.xaml.cs

using System; // IntPtr

using System.Windows; // Window, RoutedEventArgs

using System.Windows.Interop; // WindowInteropHelper

using System.Runtime.InteropServices; // DllImportAttribute

 

namespace WPFWindowWithoutIcon

{

    public partial class MainWindow : Window

    {

        [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 MainWindow()

        {

            InitializeComponent();

        }

 

        protected override void OnSourceInitialized(EventArgs e)

        {

            base.OnSourceInitialized(e);

 

            // Get this window's handle

            IntPtr hwnd = new WindowInteropHelper(this).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);

        }

    }

}

This has the effect that is demonstrated by the following figure.

In general, p/invoking to override default WPF Window behavior is totally fun, but possibly fraught with danger since WPF is essentially hWnd less ie you might do stuff to a WPF Window that makes it look weird, or that WPF simply ignores and overrides. Depending on your users, of course, weird may be good. But, nobody likes to be ignored :)

Enjoy,
Michael Weinhardt
WPF SDK

PS The sample with the code above is attached to this post.