Recently for a bit of fun I thought I would play around with Windows Presentation Foundation. I come from a Winforms background, but I never really got into WPF development as my programming career steered more towards WCF Services development.

For my simple project I thought I would write a simple little game. The game is a board game where the game resides in the main application window. What I wanted to have was another window that pops up and contains the games main menu, with options like ‘New Game’, ‘Exit’ etc.

WPF Window With Close Button
WPF Window With Close Button

When I added the code and Xaml to define the window, I noticed that the window still had a close icon on it. I wanted to get rid of this because I wanted access out of the menu to be controlled by the menu items in the centre of the screen. This was easy to do in Winforms as there was an option for it in the Visual Studio designer. Unfortunately this is not easily supported in WPF, but after a little digging I found the solution which required a little interop into user32.dll.

Xaml for Simple Window
Xaml for Simple Window

First lets look at the Xaml (in the screen shot above). This is a very typical window definition. Under the main window, I have a grid control and placed in the centre of the window are 2 TextBlocks which contain my menu options. Each TextBlock has a MouseEnter event hooked up so that as the mouse hovers over the menu items they change to a Light Red color. The TextBlocks also have a MouseUp event hooked up so that as you click on the text an action will happen. In this case for ‘New Game’ the window gets closed to show the main game window, or the ‘Exit’ option, the application is shut-down.

To get rid of the close button on the menu you have to do the following:

  • Add the following code to your class definition.
        private const int GWL_STYLE = -16;
        private const int WS_SYSMENU = 0x80000;

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
  • Hook up the Loaded event for the window and add the following code so that it looks like the following.
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var hwnd = new WindowInteropHelper(this).Handle;
            SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
        }

Once you have added this code, the window now looks like the following image:

WPF Window Without Close Button
WPF Window Without Close Button

It’s a bit of a sledgehammer approach, but it works nicely. Here is the complete code-behind file for reference.

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;

namespace Game
{
    public partial class MainMenu : Window
    {
        private const int GWL_STYLE = -16;
        private const int WS_SYSMENU = 0x80000;

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

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

        public MainMenu()
        {
            InitializeComponent();
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var hwnd = new WindowInteropHelper(this).Handle;
            SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
        }  

        private void NewGame_MouseEnter(object sender, MouseEventArgs e)
        {
            NewGame.Foreground = new SolidColorBrush(Colors.LightCoral);
            ExitGame.Foreground = new SolidColorBrush(Colors.Red);
        }

        private void ExitGame_MouseEnter(object sender, MouseEventArgs e)
        {
            NewGame.Foreground = new SolidColorBrush(Colors.Red);
            ExitGame.Foreground = new SolidColorBrush(Colors.LightCoral);
        }

        private void NewGame_MouseUp(object sender, MouseButtonEventArgs e)
        {
            this.Close();
        }

        private void ExitGame_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to exit?"Are you sure?", MessageBoxButton.YesNo,
                    MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                Application.Current.Shutdown();
            }
        }
    }
}

Advertisements

3 comments

  1. Thank you very much for this simple approach! I am new to WPF and have been looking in many places for a simplified way to remove the standard buttons, though I did have to add the following to MainWindow to make it work:
    this.Loaded += new RoutedEventHandler(Window_Loaded);

    What I would love if it’s not asking too much is an explanation on what exactly these lines do?
    [DllImport(“user32.dll”, SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport(“user32.dll”)]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s