Page 1 of 1

Disable an applications close button

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1641
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Posted 12 August 2007 - 11:16 AM

In this tutorial we will look at how to disable the close button (The x in the upper right hand corner of the application) of an application in C#. Granted, there isnt much of a call for this, I first investigated the idea when I was working on a database application a couple years ago, where, if the user inadvertanly closed the application before saving, they would lose all of their changes. If you read around on the internet you will undoubetly find many solutions, the problem is most dont account for more than one way to closing an application.

If you were to just simply disable the close button (The x in the upper right hand corner of the application), that leaves several other ways for the user to close the application. When you right-click on the title bar of an application they all have a System Menu (See image below) that also has a close option, so we need to remove that option as well.

Attached Image

Doing all this still leaves one option available for closing the application, and that is if the user presses Alt + F4, this will close the application immediately. This is probably the easiest thing to account for, simply using the Forms FormClosing event to capture this.

To disable the close button, and remove the close option from the applications System Menu, we will have to use some Application Programming Interface (API), a low level access to a Windows system, to capture several events. When using API Calls, I prefer to keep all of my API code in a seperate class file, I usually name this class Base (Since we are dealing with base level events). Lets take a look at the 3 API calls required to do what we are looking for.

public class Base
{
   [DllImport("user32")] public static extern int RemoveMenu(int systemMenu, int itemPosition, int flag)

   [DllImport("user32")] public static extern int GetSystemMenu(int systemMenu, int revert) 

   [DllImport("user32")] public static extern int GetMenuItemCount(int systemMenu)

   [DllImport("user32")] public static extern int DrawMenuBar(int currentWindow)

   //You can add to this class as you need more API Calls
}



Now we have our Base Class, the names of the methods seem self explanatory but heres a small snippet on what each does
  • RemoveMenuItem: RemoveMenu is used to remove an item from a menu. If the item being removed is a submenu, the submenu
    is not actually destroyed by this function, instead, the submenu is simply removed from the menu.

  • GetSystemMenu: GetSystemMenu is used to obtains a handle to a window's system menu. This menu is what appears when the
    application icon on the title bar is clicked, or when the title bar itself is right-clicked.

  • GetMenuItemCount: GetMenuItemCount counts the number of items in a menu. Remember, the position indexes of menu items
    are zero based. This means that if there are n items in the menu, their position indexes go from 0 to n - 1.

  • DrawMenuBar: DrawMenuBar is used to redraw the system menu so the user can see & use it.

Now that we have our Base class defined with the API Calls we need, we can concentrate on the methods for removing the Close option from the system menu. THis method, we'll name it RemoveMenuItems, will use the 4 API methods we implements in the Base class to retrieve the system menu, get a count of all the items in the system menu, remove the items we specify, then redraw the menu. Remember, Close is always the last item in the system menu, and thats the one we want to remove.

private void RemoveMenuItems(IntPtr window)
{
	int remove = 1024;
	int disable = 2;
	IntPtr menu;
	int itemCount;

	//get the system menu of the application
	menu = GetSystemMenu(window, false);

	//get the count of menu items in the system menu
	itemCount = GetMenuItemCount(menu);

	//disable the "Close" command in the menu
	RemoveMenu(menu, itemCount - 1, disable | remove);

	//now draw the menu bar on the application
	DrawMenuBar(window);
}



To remove only the "Close" option we get the count of all items in the menu, then we go to the last one, back up one (the count is zero based, so its always n-1 for the one you want) then we call the RemoveMenu API method to remove that specific item. Now when your application runs, if you right-click on the title bar to bring up the system menu, the Close option is now gone.

We have no tackled 2 of the 3 ways to close an application, the last way is if the user presses Alt + F4. To do this we will capture this in the FormCLosing event of the form. We will also give them an option to either let the application close or keep it open in case they have changes they wish to save before exiting.

private void Form1_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
{
   //get a variable to hold the users response
   DialogResult result;
   //set the variable to the messagebox results
   result = MessageBox.Show("Are you sure you want to exit this application", "Exit Application?", 

MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
   //check the users response before deciding what to do
   if (result == Windows.Forms.DialogResult.OK) //user clicked ok
   {	
	//close the application
	e.Cancel = false;
   }
   else //user clicked cancel
	  {	
	//keep the application open
	e.Cancel = true;
	  }
}



That is how you would disable the Close button on an application, use this carefully as you dont want to do this on all your application. Like I said, I created and used it due to the type of application I was working on, I didnt want the user to accidentaly lose changes they had made. One more thing, to use the RemoveMenuItems method, call that in the forms Load event.

private void MainForm_Load(object sender, System.EventArgs e)
{
   RemoveMenuItems(Handle);
}



Now you have all the tools you need for disabling the applications close button.

Happy Coding!

Is This A Good Question/Topic? 2
  • +

Replies To: Disable an applications close button

#2 jasan  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 10-April 08

Posted 10 April 2008 - 03:27 AM

Hi,

Disabling a close button from system menu is working fine
with API

but it does not actually removes the close button from the menu bar. when the mouse is hovered there, the portion of close button is highlighted

and when clicking that closes the form which is meaningless.

Pls provide another solution RemoveMenuItem

Thanks

This post has been edited by jasan: 10 April 2008 - 03:48 AM

Was This Post Helpful? 0
  • +
  • -

#3 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1641
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Posted 10 April 2008 - 04:27 AM

Ill look into what you're saying, but I just compiled and ran a sample application with this code and the close button was indeed gone. So I'm going to try to reproduce what you're saying :)
Was This Post Helpful? 0
  • +
  • -

#4 jasan  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 10-April 08

Posted 10 April 2008 - 09:50 PM

View PostPsychoCoder, on 10 Apr, 2008 - 04:27 AM, said:

Ill look into what you're saying, but I just compiled and ran a sample application with this code and the close button was indeed gone. So I'm going to try to reproduce what you're saying :)


Thanks Author.

I am also trying.

Thanks for trying the soln.
Was This Post Helpful? 0
  • +
  • -

#5 W3bDev  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 42
  • View blog
  • Posts: 379
  • Joined: 15-March 09

Posted 24 August 2009 - 01:39 PM

Thanks Psyc! You rock man.
Was This Post Helpful? 0
  • +
  • -

#6 harshaat  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 02-February 09

Posted 13 September 2009 - 12:36 AM

hi,
i have one more requirement where i have to disable | remove SAVE AS option from File menu
how can i do that
pls help
Rgs
harsha

This post has been edited by harshaat: 13 September 2009 - 12:38 AM

Was This Post Helpful? 0
  • +
  • -

#7 eURe  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 50
  • Joined: 27-October 09

Posted 27 October 2009 - 08:29 AM

Hi there;

I m just a begginer to C#, i would certainly wanted to make the code provided work as expected, I have included using System.Runtime.InteropServices; however, when i compile it, the sysem complain tht the method of 'GetMenuItemCount', 'RemoveMenu', 'DrawMenuBar' and 'Windows' does not exist in the current context, what should i do with this?

Thank you.
Was This Post Helpful? 0
  • +
  • -

#8 chat2learn  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 23-January 10

Posted 23 January 2010 - 05:30 AM

Here you would find a very easy solution. you know I spent a lot of time on this issue myself. At the end, I found this easy solution here.



I really love forums and they way you easily get your issues fixed.

Kiss
Was This Post Helpful? 0
  • +
  • -

#9 dvd4954  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 11-April 10

Posted 11 April 2010 - 02:29 AM

It still can't tackle End Task action in Task Manager, while Antivirus Program can.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1