locked
How to enable/disable the close button('X') in window form ? RRS feed

  • Question

  • Hi All,

    I would like to disable/enable the close button('X') on the window form.

    Does someone know how to do?

    Thanks,

    walker

    Tuesday, March 20, 2007 8:40 AM

Answers

  • Hi, slow walker

    There are two ways to do so:

    Method 1(simplest way): Set form.controlBox to false in form class

     this.ControlBox = false;

    (However this method will also erase the maximum and minimum box.)

    Method 2: Interoperate with the windows API provided

    [DllImport("user32", EntryPoint = "GetSystemMenu", SetLastError = true,
    CharSet 
    = CharSet.Unicode, ExactSpelling = true,
    CallingConvention 
    = CallingConvention.Winapi)]
    private static extern IntPtr GetSystemMenu(IntPtr hwnd, int bRevert);

    [DllImport(
    "user32", EntryPoint = "DeleteMenu", SetLastError = true,
    CharSet 
    = CharSet.Unicode, ExactSpelling = true,
    CallingConvention 
    = CallingConvention.Winapi)]
    private static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

    [DllImport(
    "user32", EntryPoint = "GetMenuItemCount", SetLastError = true,
    CharSet 
    = CharSet.Unicode, ExactSpelling = true,
    CallingConvention 
    = CallingConvention.Winapi)]
    private static extern int GetMenuItemCount(IntPtr hMenu);

    int mf_byposition = 0x00000400;

    And use as:

    IntPtr longVal = GetSystemMenu(this.Handle, 0);
    int longCount = GetMenuItemCount(longVal);

    DeleteMenu(longVal, longCount 
    - 1, mf_byposition);

    (remember to put the reference at the beginning: using System.Runtime.InteropServices)

    Thank you

    Wednesday, March 21, 2007 10:22 AM
  • Here is a simple and easy way that i used in my form.

    You will need the Runtime.InteropServices namespace included in ur code.

    Importing the WIN32 API

    [DllImport("user32")]
    private static extern int GetSystemMenu(IntPtr hWnd, bool bRevert);

    [DllImport("user32")]
    private static extern bool DeleteMenu(int hMenu, int uPosition, int uFlags);

    private int s_SystemMenuHandle = 0;

    private void cmdDisableX_Click(object sender, EventArgs e)
    {
                   this.s_SystemMenuHandle = GetSystemMenu(this.Handle, false);
                    DeleteMenu(
    this.s_SystemMenuHandle, 6, 1024);
    }

    private void cmdEnableX_Click(object sender, EventArgs e)
    {
                 this.s_SystemMenuHandle = GetSystemMenu(this.Handle, true);
                 DeleteMenu(
    this.s_SystemMenuHandle, 6, 1024);
    }

    You are done. Enjoy!!!

     

    Regards

    Suan Ngaihte

    Wednesday, March 21, 2007 12:25 PM

All replies

  • There's no out-of-box support from C# for this. You'll need to use win32 calls. A simple (and using C# only) solution is to set the ControlBox property of the form to false - but this removes everything - icon, min button, max button, and the close button.
    Tuesday, March 20, 2007 9:37 AM
  • Hi,

    It seems ,it's not possible to do this with any property or function.

    But u can implement logic to cancel the closing the event , in

    FormClosing(object sender, FormClosingEventArgs e) function

    My idea:

      //Some how u have to confirm that user has pressed the X button on the form

     // It can be decided by setting a flag, where ever use this.Close(). So , if the flag is set, means, the form is getting closed by some other action other than pressing this X button on the form.

     //If the flag is not set ->implies , user has pressed the X button on the form , so can cancel the event , using

      e.Cancel = true; - instruction

    I tested with a button on form.

    In buttonclick_handler, i set the flag - CanCloseForm= true;

    and called this.Close()).

    In the form_closing event i checked this flag

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)

    {

          e.Cancel = !CanCloseForm;

    }

     

    Thanx,

    Ch.T.Gopi Kumar.

     

     

    }

    Tuesday, March 20, 2007 9:53 AM
  • Hi, slow walker

    There are two ways to do so:

    Method 1(simplest way): Set form.controlBox to false in form class

     this.ControlBox = false;

    (However this method will also erase the maximum and minimum box.)

    Method 2: Interoperate with the windows API provided

    [DllImport("user32", EntryPoint = "GetSystemMenu", SetLastError = true,
    CharSet 
    = CharSet.Unicode, ExactSpelling = true,
    CallingConvention 
    = CallingConvention.Winapi)]
    private static extern IntPtr GetSystemMenu(IntPtr hwnd, int bRevert);

    [DllImport(
    "user32", EntryPoint = "DeleteMenu", SetLastError = true,
    CharSet 
    = CharSet.Unicode, ExactSpelling = true,
    CallingConvention 
    = CallingConvention.Winapi)]
    private static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

    [DllImport(
    "user32", EntryPoint = "GetMenuItemCount", SetLastError = true,
    CharSet 
    = CharSet.Unicode, ExactSpelling = true,
    CallingConvention 
    = CallingConvention.Winapi)]
    private static extern int GetMenuItemCount(IntPtr hMenu);

    int mf_byposition = 0x00000400;

    And use as:

    IntPtr longVal = GetSystemMenu(this.Handle, 0);
    int longCount = GetMenuItemCount(longVal);

    DeleteMenu(longVal, longCount 
    - 1, mf_byposition);

    (remember to put the reference at the beginning: using System.Runtime.InteropServices)

    Thank you

    Wednesday, March 21, 2007 10:22 AM
  • Here is a simple and easy way that i used in my form.

    You will need the Runtime.InteropServices namespace included in ur code.

    Importing the WIN32 API

    [DllImport("user32")]
    private static extern int GetSystemMenu(IntPtr hWnd, bool bRevert);

    [DllImport("user32")]
    private static extern bool DeleteMenu(int hMenu, int uPosition, int uFlags);

    private int s_SystemMenuHandle = 0;

    private void cmdDisableX_Click(object sender, EventArgs e)
    {
                   this.s_SystemMenuHandle = GetSystemMenu(this.Handle, false);
                    DeleteMenu(
    this.s_SystemMenuHandle, 6, 1024);
    }

    private void cmdEnableX_Click(object sender, EventArgs e)
    {
                 this.s_SystemMenuHandle = GetSystemMenu(this.Handle, true);
                 DeleteMenu(
    this.s_SystemMenuHandle, 6, 1024);
    }

    You are done. Enjoy!!!

     

    Regards

    Suan Ngaihte

    Wednesday, March 21, 2007 12:25 PM
  •  

    This is how I've disabled a Windows Forms close box in C#:

     

    using System.Runtime.InteropServices;

     

    // Declare P/Invoke methods

    [ DllImport("user32")]

    private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool revert);

    [DllImport("user32")]

    private static extern int EnableMenuItem(IntPtr hWndMenu, int itemID, int enable);

     

    // Declare constants (from winuser.h) to pass to the methods

    private const int SC_CLOSE      = 0xF060;

    private const int MF_ENABLED  = 0x0000;

    private const int MF_GREYED   = 0x0001;

     

    private bool closeBoxEnabled = true;

     

    public bool CloseEnabled

    {

      get { return closeBoxEnabled; }

      set {

        EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE,

          value ? MF_ENABLED : MF_GREYED);

     

        closeBoxEnabled = value;

      }

    }

     

     

    If you search for GetSystemMenu() in MSDN you'll find this solution described.

     

     

    Friday, March 30, 2007 3:22 PM
  • I tried this solution but the close button of the form is shown as grey though it is enabled

    private void cmdDisableX_Click(object sender, EventArgs e)
    {
                   this.s_SystemMenuHandle = GetSystemMenu(this.Handle, false);
                    DeleteMenu(
    this.s_SystemMenuHandle, 6, 1024);
    }

    private void cmdEnableX_Click(object sender, EventArgs e)
    {
                 this.s_SystemMenuHandle = GetSystemMenu(this.Handle, true);
                 DeleteMenu(
    this.s_SystemMenuHandle, 6, 1024);
    }

    Monday, August 12, 2013 11:07 AM