Reputation: 1598
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:
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
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
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
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
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