Paul Williams
Paul Williams

Reputation: 1598

How to prevent ALT+F4 of a WinForm but allow all other forms of closing a WinForm?

I've searched around the interwebs and various parts of this resource where this question was asked and noticed I got the following bits of code:

Protected Overrides ReadOnly Property CreateParams() As CreateParams
    Get
        Dim cp As CreateParams = MyBase.CreateParams
        Const CS_NOCLOSE As Integer = &H200
        cp.ClassStyle = cp.ClassStyle Or CS_NOCLOSE
        Return cp
    End Get
End Property

Which works as intended, this does disable ALT+F4 from being used. However, as an unintended side effect of this code: closing the window via the Control Box is disabled:

Closing "X" is disabled

Is there a version of this code that disables ALT+F4 BUT still allows for the closing of the window via its control box or other UI options (such as a close button and a Close option in a menu.)

I know someone will say to check the e.CloseReason of the form, however UserClosing is the only reason the resembles what I would like to do, however... that still disables the UI from being used. Unless there is a code that I forgot about.

Upvotes: 4

Views: 1382

Answers (4)

Luiz
Luiz

Reputation: 208

Easy:

In C#

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == (Keys.Alt | Keys.F4))
    {
        return true;  // The key is manually processed
    }
    else
        return base.ProcessCmdKey(ref msg, keyData);
}

In VB.Net

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
    If keyData = (Keys.Alt Or Keys.F4) Then
        Return True
    Else
        Return MyBase.ProcessCmdKey(msg, keyData)
    End If
End Function

Upvotes: 0

Visual Vincent
Visual Vincent

Reputation: 18310

Answer to your comment, handling KeyDown from a separate class.

Documentation:

Public NotInheritable Class MainInterface
    Private Sub New() 'No constructor.
    End Sub

    Public Shared Sub DisableAltF4(ByVal TargetForm As Form)
        TargetForm.KeyPreview = True
        AddHandler TargetForm.KeyDown, AddressOf Form_KeyDown
    End Sub

    Private Shared Sub Form_KeyDown(sender As Object, e As KeyEventArgs)
        e.Handled = (e.Alt AndAlso e.KeyCode = Keys.F4)
    End Sub
End Class

Now in every form's Load event handler you can do:

Private Sub yourForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    MainInterface.DisableAltF4(Me)
End Sub

As Olaf said you can also make all forms inherit from a base class. However this might get a little bit more complicated as you have to tell both the yourForm.vb and the yourForm.Designer.vb file that you want to inherit from the base form.

Public Class BaseForm
    Inherits Form

    Protected Overrides Sub OnLoad(e As System.EventArgs)
        MyBase.OnLoad(e)
        Me.KeyPreview = True
    End Sub

    Protected Overrides Sub OnKeyDown(e As System.Windows.Forms.KeyEventArgs)
        MyBase.OnKeyDown(e)
        e.Handled = e.Handled OrElse (e.Alt AndAlso e.KeyCode = Keys.F4)
    End Sub
End Class

In yourForm.vb:

Public Class yourForm
    Inherits BaseForm

    ...code...
End Class

In yourForm.Designer.vb:

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class yourForm
    Inherits yourNamespace.BaseForm

    ...code...
End Class

Upvotes: 1

Olaf
Olaf

Reputation: 76

Set KeyPreview = True and handle the KeyDown event:

Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    If e.Alt AndAlso e.KeyCode = Keys.F4 Then
        e.Handled = True
    End If
End Sub

Upvotes: 2

KBO
KBO

Reputation: 671

You should also remove the corresponding CLOSE menu item from the forms system menu using a RemoveMenu() interop call. This disables all default window close options.

Of course you can call Form.Close() in your code to close your form. That can be triggered by a Click event handler of a custom button, menu item etc. Additionally, you can implement an System.Windows.Forms.IMessageFilter to handle a custom key sequence (instead of ALT+F4) to close your form, e.g. C+L+O+S+E.

Upvotes: 0

Related Questions