How do I go about changing what happens when a user clicks the close (red X) button in a Windows Forms application (in C#)?
protected override bool ProcessCmdKey(ref Message msg, Keys dataKey)
{
if (dataKey == Keys.Escape)
{
this.Close();
//this.Visible = false;
//Plus clear values from form, if Visible false.
}
return base.ProcessCmdKey(ref msg, dataKey);
}
This is a pretty commonly asked question. One good answer is here:
VB.NET overload default functionality when user clicks the X (Close Program)
If you don't feel comfortable putting your code in the Form_Closing event, the only other option I am aware of is a "hack" that I've used once or twice. It should not be necessary to resort to this hack, but here it is:
Don't use the normal close button. Instead, create your form so that it has no ControlBox. You can do this by setting ControlBox = false on the form, in which case, you will still have the normal bar across the top of the form, or you can set the form's FormBorderStyle to "None. If you go this second route, there will be no bar across the top, or any other visible border, so you'll have to simulate those either by drawing on the form, or by artistic use of Panel controls.
Then you can add a standard button and make it look like a close button, and put your clean-up code in there. At the end of the button event, just call this.Close()
(C#) or Me.Close()
(VB)
One situation where it is quite useful to be able to handle the x-button click event is when you are using a Form that is an MDI container. The reason is that the closeing and closed events are raised first with children and lastly with the parent. So in one scenario a user clicks the x-button to close the application and the MDI parent asks for a confirmation to proceed. In case he decides to not close the application but carry on whatever he is doing the children will already have processed the closing event potentially lost information/work whatever. One solution is to intercept the WM_CLOSE message from the Windows message loop in your main application form (i.e. which closed, terminates the application) like so:
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0010) // WM_CLOSE
{
// If we don't want to close this window
if (ShowConfirmation("Are you sure?") != DialogResult.Yes) return;
}
base.WndProc(ref m);
}
The accepted answer works quite well. An alternative method that I have used is to create a FormClosing method for the main Form. This is very similar to the override. My example is for an application that minimizes to the system tray when clicking the close button on the Form.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.ApplicationExitCall)
{
return;
}
else
{
e.Cancel = true;
WindowState = FormWindowState.Minimized;
}
}
This will allow ALT+F4 or anything in the Application calling Application.Exit(); to act as normal while clicking the (X) will minimize the Application.