如何防止WinForm的ALT + F4,但允许所有其他形式的关闭WinForm?

时间:2017-08-04 06:07:34

标签: vb.net winforms event-handling

我搜索了这个问题的互联网和资源的各个部分,并注意到我得到了以下几点代码:

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

按预期工作,这会禁用ALT + F4。但是,作为此代码的意外副作用:禁用通过控制框关闭窗口

Closing "X" is disabled

是否存在disables ALT+F4此代码的版本仍然允许通过其控制框或其他UI选项关闭窗口(例如菜单中的关闭按钮和关闭选项)。

我知道有人会说要检查e.CloseReason of the form,但是UserClosing是我想要做的事情的唯一原因,但是......仍然会禁用用户界面。除非有我遗忘的代码。

4 个答案:

答案 0 :(得分:2)

设置KeyPreview = True并处理KeyDown事件:

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

答案 1 :(得分:1)

回答你的评论,从另一个班级处理KeyDown

<强>文档

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

现在,您可以执行以下各种形式的Load事件处理程序:

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

正如奥拉夫所说,你也可以使所有形式都从基类继承。但是,由于您必须告诉要从基本表单继承的yourForm.vbyourForm.Designer.vb文件,这可能会变得更复杂。

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

yourForm.vb

Public Class yourForm
    Inherits BaseForm

    ...code...
End Class

yourForm.Designer.vb

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

    ...code...
End Class

答案 2 :(得分:0)

您还应该使用RemoveMenu()互操作呼叫从表单系统菜单中删除相应的CLOSE菜单项。这将禁用所有默认窗口关闭选项。

当然,您可以在代码中调用Form.Close()来关闭表单。这可以由自定义按钮,菜单项等的Click事件处理程序触发。此外,您可以实现System.Windows.Forms.IMessageFilter来处理自定义键序列(而不是ALT + F4)来关闭表单,例如C + L + O + S + E

答案 3 :(得分:0)

易:

在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);
}

在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