83

What is the best way to disable Alt + F4 in a c# win form to prevent the user from closing the form?

I am using a form as a popup dialog to display a progress bar and I do not want the user to be able to close it.

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Ryan Sampson
  • 6,717
  • 12
  • 47
  • 55
  • Within the FormClosing event handler could you not interrogate the keyboard buffer (do you even have access to this?) to se if [Alt] + [F4] was pressed, cancel if true, continue if not? – TK. Aug 18 '08 at 17:38

11 Answers11

110

This does the job:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true;
}

Edit: In response to pix0rs concern - yes you are correct that you will not be able to programatically close the app. However, you can simply remove the event handler for the form_closing event before closing the form:

this.FormClosing -= new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Close();
Martin
  • 39,569
  • 20
  • 99
  • 130
  • 4
    I suspect most people are implementing this method on the form in question (Form1). In this case, it is recommended you do not attach a delegate, but instead override the OnFormClosing method. "The OnFormClosing method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class." http://tinyurl.com/3dzzljq – antsyawn May 26 '11 at 04:09
  • 11
    I would have made the event handler as such: `e.Cancel = (e.Reason == CloseReason.UserClosing);`. This way you guarantee that you won't close only when the USER tries to close the form. – Paulo Santos Aug 05 '11 at 11:37
  • 1
    This approach has one big problem: if you want to shutdown/restart your PC it will cancel that request too, (at least on Windows XP) – conceptacid Apr 03 '14 at 13:59
  • That's BRILLIANT! I especially love removing the event when you want to close the form. It's so SIMPLE!!! – Will Apr 10 '14 at 15:10
  • @Will: I've edited the answer. There's now a solution that works without removing the event handler. – Thomas Weller Sep 02 '18 at 13:06
62

If you look at the value of FormClosingEventArgs e.CloseReason, it will tell you why the form is being closed. You can then decide what to do, the possible values are:

Member name - Description


None - The cause of the closure was not defined or could not be determined.

WindowsShutDown - The operating system is closing all applications before shutting down.

MdiFormClosing - The parent form of this multiple document interface (MDI) form is closing.

UserClosing - The user is closing the form through the user interface (UI), for example by clicking the Close button on the form window, selecting Close from the window's control menu, or pressing ALT+F4.

TaskManagerClosing - The Microsoft Windows Task Manager is closing the application.

FormOwnerClosing - The owner form is closing.

ApplicationExitCall - The Exit method of the Application class was invoked.

Patrick
  • 674
  • 1
  • 8
  • 22
Matt Warren
  • 10,279
  • 7
  • 48
  • 63
27

I believe this is the right way to do it:

protected override void OnFormClosing(FormClosingEventArgs e)
{
  switch (e.CloseReason)
  {
    case CloseReason.UserClosing:
      e.Cancel = true;
      break;
  }

  base.OnFormClosing(e);
}
antsyawn
  • 971
  • 10
  • 17
  • better replace the break with return – Bahadır Yağan Apr 24 '11 at 20:30
  • Actually I believe the correct pattern is to set the cancel flag to true and then call the base class. When overriding On[Event] methods it is important to call the base class so that any event subscribers are also notified of the event. Yes in this case it's easy to think that since you've cancelled the event then no one else needs to know about it, but I don't believe it correct to make that assumption. – antsyawn Apr 27 '11 at 23:48
  • I am not sure about the reason, but if I call the base class, my application crashes after another subsequent Alt+F4 hit. At first I thought it was because plain F4 has some other meaning in my application, but a long debugging session showed otherwise. Anyway, it may still be a specific case on my side. Thanks for this great answer. – Bahadır Yağan Apr 28 '11 at 20:30
  • Calling the base class also causes my app to crash on subsequent Alt+F4s. I suspect the base class doesn't check e.Cancel and tries to destroy the form anyway. – Natan Yellin May 24 '11 at 15:46
  • You need to look into why your application is crashing - it is likely you are doing something wrong elsewhere. The docs say "The FormClosing event occurs as the form is being closed. When a form is closed, it is disposed, releasing all resources associated with the form. If you cancel this event, the form remains opened. To cancel the closure of a form, set the Cancel property of the FormClosingEventArgs passed to your event handler to true." http://tinyurl.com/3tb7y9q – antsyawn May 26 '11 at 04:06
  • You should not call base.OnFormClosing(e) inside the form closing. It causes stack overflow exception and your app will be crashed. – Azadeh Radkianpour Dec 29 '14 at 09:34
16

Note that it is considered bad form for an application to completely prevent itself from closing. You should check the event arguments for the Closing event to determine how and why your application was asked to close. If it is because of a Windows shutdown, you should not prevent the close from happening.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
13

You could handle the FormClosing event and set FormClosingEventArgs.Cancel to true.

Timbo
  • 27,472
  • 11
  • 50
  • 75
12

I am using a form as a popup dialog to display a progress bar and I do not want the user to be able to close it.

If the user is determined to close your app (and knowledgeable) enough to press alt+f4, they'll most likely also be knowledgeable enough to run task manager and kill your application instead.

At least with alt+f4 your app can do a graceful shutdown, rather than just making people kill it. From experience, people killing your app means corrupt config files, broken databases, half-finished tasks that you can't resume, and many other painful things.

At least prompt them with 'are you sure' rather than flat out preventing it.

Orion Edwards
  • 121,657
  • 64
  • 239
  • 328
7

This is a hack to disable Alt + F4.

private void test_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.ModifierKeys == Keys.Alt || this.ModifierKeys == Keys.F4) 
    { 
        e.Cancel = true; 
    }    
}
Patrick
  • 674
  • 1
  • 8
  • 22
Brahim Bourass
  • 129
  • 1
  • 2
  • 1
    I can confirm this does work. However, if using `System.Windows.Forms`, you will need to check the static `Control.ModifierKeys` property, instead of the `this.ModifierKeys` property (as shown in the snippet above). – Special Sauce Sep 14 '19 at 00:14
  • This approach is better because this way you can allow your application to be closed with the Close() method, which shares the CloseReason.UserClosing reason. My concern with this approach is that is the currently pressed key information always be accurate? – Adam L. S. Nov 11 '20 at 10:12
4

Subscribe FormClosing event

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = e.CloseReason == CloseReason.UserClosing;
}

Only one line in the method body.

linquize
  • 19,828
  • 10
  • 59
  • 83
3

This does the job:

bool myButtonWasClicked = false;
private void Exit_Click(object sender, EventArgs e)
{
  myButtonWasClicked = true;
  Application.Exit();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
  if (myButtonWasClicked)
  {
    e.Cancel = false;
  }
  else
  {
    e.Cancel = true;
  }


}
2

Would FormClosing be called even when you're programatically closing the window? If so, you'd probably want to add some code to allow the form to be closed when you're finished with it (instead of always canceling the operation)

pix0r
  • 31,139
  • 18
  • 86
  • 102
  • The answer to your question is "yes". Please don't post additional questions as an answer. There's already a really good, highly voted and accepted answer. If you don't mind, would you please delete yours? It doesn't really add value. I've upvoted 3 of your answers to compensate for the deletion. – Thomas Weller Sep 02 '18 at 13:09
-3

Hide close button on form by using the following in constructor of the form:

this.ControlBox = false;
user229044
  • 232,980
  • 40
  • 330
  • 338
Bharath theorare
  • 524
  • 7
  • 27