Remove the Close button from a form’s system menu in C#

[system menu]

C# doesn’t have a built-in way to manipulate the system menu that appears when you click the upper left corner of a form, but it’s not too hard to use API functions to remove some or all of those buttons.

This example uses the following using statements to declare the API functions that it needs to remove the X command from the menu.

using System.Runtime.InteropServices;
...
// Declare User32 constants and methods.
private const int MF_BYPOSITION = 0x400;

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

[DllImport("User32")]
private static extern int
    GetMenuItemCount(IntPtr hWnd);

[DllImport("User32")]
private static extern int
    RemoveMenu(IntPtr hMenu, int nPosition, int wFlags);

// Remove the X button.
private void Form1_Load(object sender, EventArgs e)
{
    IntPtr hMenu = GetSystemMenu(this.Handle, false);
    int num_menu_items = GetMenuItemCount(hMenu);
    RemoveMenu(hMenu, num_menu_items - 1, MF_BYPOSITION);
    RemoveMenu(hMenu, num_menu_items - 2, MF_BYPOSITION);
}

This code first defines the GetSystemMenu, GetMenuItemCount, and RemoveMenu API functions.

The form’s Load event handler uses GetSystemMenu to get the handle for the form’s system menu. It then uses GetMenuItemCount to see how many items the menu contains. Next it calls RemoveMenu twice to remove the Close menu item and the separator that comes before it in the menu.

You can see in the picture that the X menu item and the separator before it has been completely removed. You can also see that the X close button in the form’s upper right corner is disabled. (It would have a red background if it were enabled.)

Notice that the code removes the menu’s last item first and then removes the second-to-last item second. If it tried to remove the second-to-last item first, then the menu would have one fewer item when the code tried to remove the last item so it wouldn’t work. The code should only remove items in positions that exist at the time.

If you remove all of the system’s menu items, the user will not be able to move, resize, or close the form, and the form’s system menu will not appear. However the system menu’s symbol still appears in the form’s upper left corner, the cursor still changes to the resize cursor when you hold it over the form’s borders, and the minimize and maximize buttons still work. All in all, this is pretty confusing to the user. If you want to remove that menu completely, set the form’s ControlBox property to False instead.

Also note that none of these techniques prevent the user from closing the form by pressing Alt+F4. You can use the form’s FormClosing event to prevent that.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in API, forms, system and tagged , , , , , , , , , , . Bookmark the permalink.

2 Responses to Remove the Close button from a form’s system menu in C#

  1. Christopher Harris says:

    While this does remove the Close system menu item, it does not work to “Remove the X Close button from a form’s system menu in C#”. Note: the ‘X’ button is still visible. This only disabled the button.

  2. Rod Stephens says:

    True. You are usually better off removing the menu and X by setting the form’s ControlBox property to false. Of course then you also lose the minimize and maximize buttons.

    Or you can catch the form’s FormClosing event, figure out why the form is closing, a prevent it if the user didn’t use the button or whatever that you provided.

    Probably the best bet is to either leave the Close item and X there and deal with it in FormClosing, or remove the whole control box.

    (The X button has been a bit of a headache for quite a few years.)

Leave a Reply

Your email address will not be published. Required fields are marked *