locked
How do I make a Window with a border but no close button? RRS feed

Answers

  • Hi Zappo1980,

    i am confused by your description, what is your needs, could you share a pic with me with the effect after set WindowStyle="None"  on your side?

    I think you did some other setting for your windows.

    best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Sheldon _Xiao Friday, October 19, 2012 2:20 AM
    Wednesday, October 17, 2012 12:14 PM
  • You may wish to have a look at this thread too

    http://stackoverflow.com/questions/3386486/wpf-make-window-unresizeable-but-keep-the-frame

    Cheers,
    Matt

    • Marked as answer by Sheldon _Xiao Friday, October 19, 2012 2:20 AM
    Thursday, October 18, 2012 2:53 AM
  • Thanks. Based on Eric's and Cameron's answers on that thread, I've come up with this:

            private const int GWL_STYLE = -16;
            private const int WS_SYSMENU = 0x80000;
            private const int WS_MAXIMIZEBOX = 0x00010000;
            private const int WS_MINIMIZEBOX = 0x00020000;
            [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);
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
    
            private void SetGlassBorder()
            {
                // Obtain the window handle for WPF application
                IntPtr hwnd = new WindowInteropHelper(this).Handle;
                // Hide system buttons
                SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
                HwndSource mainWindowSrc = HwndSource.FromHwnd(hwnd);
                // Add window proc hook
                mainWindowSrc.AddHook(WndProc);
            }
    
            private const int WM_NCHITTEST = 0x0084;
            private const int HTBORDER = 18;
            private const int HTBOTTOM = 15;
            private const int HTBOTTOMLEFT = 16;
            private const int HTBOTTOMRIGHT = 17;
            private const int HTLEFT = 10;
            private const int HTRIGHT = 11;
            private const int HTTOP = 12;
            private const int HTTOPLEFT = 13;
            private const int HTTOPRIGHT = 14;
    
            private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
            {
                // Override the window hit test and if the cursor is over a resize border, return a standard border result instead.
                if (msg == WM_NCHITTEST)
                {
                    handled = true;
                    var htLocation = DefWindowProc(hwnd, msg, wParam, lParam).ToInt32();
                    switch (htLocation)
                    {
                        case HTBOTTOM:
                        case HTBOTTOMLEFT:
                        case HTBOTTOMRIGHT:
                        case HTLEFT:
                        case HTRIGHT:
                        case HTTOP:
                        case HTTOPLEFT:
                        case HTTOPRIGHT:
                            htLocation = HTBORDER;
                            break;
                    }
    
                    return new IntPtr(htLocation);
                }
    
                return IntPtr.Zero;
            }

    When called on a window with WindowStyle="None" and ResizeMode="CanResize", that SetGlassBorder() function will result in a glass border without resizing.

    I'd say that solves it. Thanks everyone!

    • Marked as answer by Zappo1980 Thursday, October 18, 2012 7:35 AM
    Thursday, October 18, 2012 7:35 AM

All replies

  • Please find the following link for hiding the close button, with all the buttons hidden now, use empty window title.

    http://julmar.com/blog/mark/?p=17


    If a post answers your question, please click "Mark As Answer" and "Mark as Helpful" on that post.

    Monday, October 8, 2012 11:04 AM
  • Hi Zappo1980,

    As for remove Maximize and Minimize buttons, you could use this method provide by others:

    <Window x:Class="WindowCustomizerExample.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:local="clr-namespace:WindowCustomizerExample"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            local:WindowCustomizer.CanMaximize="False"
            local:WindowCustomizer.CanMinimize="False"
            Loaded="Window_Loaded">
    </Window>
    namespace WindowCustomizerExample
    {
        public static class WindowCustomizer
        {
            #region CanMaximize
            public static readonly DependencyProperty CanMaximize =
                DependencyProperty.RegisterAttached("CanMaximize", typeof(bool), typeof(Window),
                    new PropertyMetadata(true, new PropertyChangedCallback(OnCanMaximizeChanged)));
            private static void OnCanMaximizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                Window window = d as Window;
                if (window != null)
                {
                    RoutedEventHandler loadedHandler = null;
                    loadedHandler = delegate
                    {
                        if ((bool)e.NewValue)
                        {
                            WindowHelper.EnableMaximize(window);
                        }
                        else
                        {
                            WindowHelper.DisableMaximize(window);
                        }
                        window.Loaded -= loadedHandler;
                    };
    
                    if (!window.IsLoaded)
                    {
                        window.Loaded += loadedHandler;
                    }
                    else
                    {
                        loadedHandler(null, null);
                    }
                }
            }
            public static void SetCanMaximize(DependencyObject d, bool value)
            {
                d.SetValue(CanMaximize, value);
            }
            public static bool GetCanMaximize(DependencyObject d)
            {
                return (bool)d.GetValue(CanMaximize);
            }
            #endregion CanMaximize
    
            #region CanMinimize
            public static readonly DependencyProperty CanMinimize =
                DependencyProperty.RegisterAttached("CanMinimize", typeof(bool), typeof(Window),
                    new PropertyMetadata(true, new PropertyChangedCallback(OnCanMinimizeChanged)));
            private static void OnCanMinimizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                Window window = d as Window;
                if (window != null)
                {
                    RoutedEventHandler loadedHandler = null;
                    loadedHandler = delegate
                    {
                        if ((bool)e.NewValue)
                        {
                            WindowHelper.EnableMinimize(window);
                        }
                        else
                        {
                            WindowHelper.DisableMinimize(window);
                        }
                        window.Loaded -= loadedHandler;
                    };
    
                    if (!window.IsLoaded)
                    {
                        window.Loaded += loadedHandler;
                    }
                    else
                    {
                        loadedHandler(null, null);
                    }
                }
            }
            public static void SetCanMinimize(DependencyObject d, bool value)
            {
                d.SetValue(CanMinimize, value);
            }
            public static bool GetCanMinimize(DependencyObject d)
            {
                return (bool)d.GetValue(CanMinimize);
            }
            #endregion CanMinimize
    
            #region WindowHelper Nested Class
            public static class WindowHelper
            {
                private const Int32 GWL_STYLE = -16;
                private const Int32 WS_MAXIMIZEBOX = 0x00010000;
                private const Int32 WS_MINIMIZEBOX = 0x00020000;
    
                [DllImport("User32.dll", EntryPoint = "GetWindowLong")]
                private extern static Int32 GetWindowLongPtr(IntPtr hWnd, Int32 nIndex);
    
                [DllImport("User32.dll", EntryPoint = "SetWindowLong")]
                private extern static Int32 SetWindowLongPtr(IntPtr hWnd, Int32 nIndex, Int32 dwNewLong);
    
                /// <summary>
                /// Disables the maximize functionality of a WPF window.
                /// </summary>
                /// <param name="window">The WPF window to be modified.</param>
                public static void DisableMaximize(Window window)
                {
                    lock (window)
                    {
                        IntPtr hWnd = new WindowInteropHelper(window).Handle;
                        Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
                        SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle & ~WS_MAXIMIZEBOX);
                    }
                }
    
                /// <summary>
                /// Disables the minimize functionality of a WPF window.
                /// </summary>
                /// <param name="window">The WPF window to be modified.</param>
                public static void DisableMinimize(Window window)
                {
                    lock (window)
                    {
                        IntPtr hWnd = new WindowInteropHelper(window).Handle;
                        Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
                        SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle & ~WS_MINIMIZEBOX);
                    }
                }
    
                /// <summary>
                /// Enables the maximize functionality of a WPF window.
                /// </summary>
                /// <param name="window">The WPF window to be modified.</param>
                public static void EnableMaximize(Window window)
                {
                    lock (window)
                    {
                        IntPtr hWnd = new WindowInteropHelper(window).Handle;
                        Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
                        SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle | WS_MAXIMIZEBOX);
                    }
                }
    
                /// <summary>
                /// Enables the minimize functionality of a WPF window.
                /// </summary>
                /// <param name="window">The WPF window to be modified.</param>
                public static void EnableMinimize(Window window)
                {
                    lock (window)
                    {
                        IntPtr hWnd = new WindowInteropHelper(window).Handle;
                        Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
                        SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle | WS_MINIMIZEBOX);
                    }
                }
    
                /// <summary>
                /// Toggles the enabled state of a WPF window's maximize functionality.
                /// </summary>
                /// <param name="window">The WPF window to be modified.</param>
                public static void ToggleMaximize(Window window)
                {
                    lock (window)
                    {
                        IntPtr hWnd = new WindowInteropHelper(window).Handle;
                        Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
    
                        if ((windowStyle | WS_MAXIMIZEBOX) == windowStyle)
                        {
                            SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle & ~WS_MAXIMIZEBOX);
                        }
                        else
                        {
                            SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle | WS_MAXIMIZEBOX);
                        }
                    }
                }
    
                /// <summary>
                /// Toggles the enabled state of a WPF window's minimize functionality.
                /// </summary>
                /// <param name="window">The WPF window to be modified.</param>
                public static void ToggleMinimize(Window window)
                {
                    lock (window)
                    {
                        IntPtr hWnd = new WindowInteropHelper(window).Handle;
                        Int32 windowStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
    
                        if ((windowStyle | WS_MINIMIZEBOX) == windowStyle)
                        {
                            SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle & ~WS_MINIMIZEBOX);
                        }
                        else
                        {
                            SetWindowLongPtr(hWnd, GWL_STYLE, windowStyle | WS_MINIMIZEBOX);
                        }
                    }
                }
            }
            #endregion WindowHelper Nested Class
        }
    }

    As for remove the Close button, you could refer to this method:

     public partial class Window1 : 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 Window1()
            {
                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);
            }

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, October 9, 2012 7:11 AM
  • Hi Sheldon Xiao,

    Thanks for your help. The information you posted allowed me to hide the various system buttons, but the border is still different from the one in the example. Specifically, the top border is much thicker than the other three sides - ie, it looks just like a SingleBorderWindow without the buttons and with a blank title.

    How can I make a window that looks exactly like the first one in this Microsoft example? http://msdn.microsoft.com/en-us/library/system.windows.window.windowstyle.aspx

    Kind regards,

        Filippo

    Monday, October 15, 2012 3:56 PM
  • Hi Zappo1980,

    I think you just need to make sure you're using Aero theme on either Vista or 7, as WindowStyle="None" for me has got the thicker border but no buttons. 

    And make sure you don't have AllowsTransparency="True". You won't get a border at all with that.

    Cheers,
    Matt


    Tuesday, October 16, 2012 2:04 AM
  • Hi Zappo1980,

    If you need a single border, you could just set WindowStyle="None", however, tittle, and buttons will not show up.

    best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, October 16, 2012 3:25 AM
  • I'm using Aero on Windows 7, AllowsTransparency="False", and I'm getting no border at all. If I set BorderThickness to something greater than zero, then I get a solid black border.
    Tuesday, October 16, 2012 7:05 AM
  • WindowStyle="None" gives me no border at all. If I set BorderThickness to something greater than zero, I get a solid black border. I can't find any way to get the glass border.
    Tuesday, October 16, 2012 7:11 AM
  • Hi Zappo1980,

    i am confused by your description, what is your needs, could you share a pic with me with the effect after set WindowStyle="None"  on your side?

    I think you did some other setting for your windows.

    best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Sheldon _Xiao Friday, October 19, 2012 2:20 AM
    Wednesday, October 17, 2012 12:14 PM
  • I think you did some other setting for your windows.

    Thanks, I found it! It was my fault - I want the window to be non-resizable, so I set NoResize, which hides the border.

    But now I have a different problem: is there any way to have the glass border, but make it static (i.e. not usable for resizing)?

    Wednesday, October 17, 2012 1:43 PM
  • I think SizeChanged event of window maybe helpful for you, you could prevent the size change in this event.


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, October 18, 2012 2:37 AM
  • You may wish to have a look at this thread too

    http://stackoverflow.com/questions/3386486/wpf-make-window-unresizeable-but-keep-the-frame

    Cheers,
    Matt

    • Marked as answer by Sheldon _Xiao Friday, October 19, 2012 2:20 AM
    Thursday, October 18, 2012 2:53 AM
  • Thanks. Based on Eric's and Cameron's answers on that thread, I've come up with this:

            private const int GWL_STYLE = -16;
            private const int WS_SYSMENU = 0x80000;
            private const int WS_MAXIMIZEBOX = 0x00010000;
            private const int WS_MINIMIZEBOX = 0x00020000;
            [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);
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
    
            private void SetGlassBorder()
            {
                // Obtain the window handle for WPF application
                IntPtr hwnd = new WindowInteropHelper(this).Handle;
                // Hide system buttons
                SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
                HwndSource mainWindowSrc = HwndSource.FromHwnd(hwnd);
                // Add window proc hook
                mainWindowSrc.AddHook(WndProc);
            }
    
            private const int WM_NCHITTEST = 0x0084;
            private const int HTBORDER = 18;
            private const int HTBOTTOM = 15;
            private const int HTBOTTOMLEFT = 16;
            private const int HTBOTTOMRIGHT = 17;
            private const int HTLEFT = 10;
            private const int HTRIGHT = 11;
            private const int HTTOP = 12;
            private const int HTTOPLEFT = 13;
            private const int HTTOPRIGHT = 14;
    
            private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
            {
                // Override the window hit test and if the cursor is over a resize border, return a standard border result instead.
                if (msg == WM_NCHITTEST)
                {
                    handled = true;
                    var htLocation = DefWindowProc(hwnd, msg, wParam, lParam).ToInt32();
                    switch (htLocation)
                    {
                        case HTBOTTOM:
                        case HTBOTTOMLEFT:
                        case HTBOTTOMRIGHT:
                        case HTLEFT:
                        case HTRIGHT:
                        case HTTOP:
                        case HTTOPLEFT:
                        case HTTOPRIGHT:
                            htLocation = HTBORDER;
                            break;
                    }
    
                    return new IntPtr(htLocation);
                }
    
                return IntPtr.Zero;
            }

    When called on a window with WindowStyle="None" and ResizeMode="CanResize", that SetGlassBorder() function will result in a glass border without resizing.

    I'd say that solves it. Thanks everyone!

    • Marked as answer by Zappo1980 Thursday, October 18, 2012 7:35 AM
    Thursday, October 18, 2012 7:35 AM
  • You're welcome, and thanks for posting your solution, it's neat :)
    Thursday, October 18, 2012 9:22 PM