Need to disable\enable a Form's Close button

Here's a snippet that may help:

#Region " Enable\Disable a Form's Close Button "

Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Integer, ByVal revert As Integer) As Integer

Private Declare Function EnableMenuItem Lib "user32" (ByVal menu As Integer, ByVal ideEnableItem As Integer, ByVal enable As Integer) As Integer

Private Const SC_CLOSE As Integer = &HF060

Private Const MF_BYCOMMAND As Integer = &H0

Private Const MF_GRAYED As Integer = &H1

Private Const MF_ENABLED As Integer = &H0

Public Sub DisableFormCloseButton(ByVal form As System.Windows.Forms.Form)

' The return value specifies the previous state of the menu item (it is either

' MF_ENABLED or MF_GRAYED). 0xFFFFFFFF indicates that the menu item does not exist.

    Select Case EnableMenuItem(GetSystemMenu(form.Handle.ToInt32, 0), SC_CLOSE, MF_BYCOMMAND Or             MF_GRAYED)

        Case MF_ENABLED

        Case MF_GRAYED

        Case &HFFFFFFFF

            Throw New Exception("The Close menu item does not exist.")

        Case Else

    End Select

End Sub

Public Sub EnableFormCloseButton(ByVal form As System.Windows.Forms.Form)

    EnableMenuItem(GetSystemMenu(form.Handle.ToInt32, 0), SC_CLOSE, MF_BYCOMMAND)

End Sub

#End Region

 

Credits to the source that helped me figure this out. 

 

9 Comments

  • Doesn't seem to work if you maximize a form.

  • I don't know that you intended it maliciously, but normally when someone helps me on code, I give some credit to them for it...

  • Thanks for the link love... it's appreciated.



    I mainly blogged about it since I've seen this happen in the past and really haven't seen anyone say anything about it. It was a perfect example of the situation... you thought one thing and it was another. The second portion of the code, although did come from the SDK as to the "what to do", the VB code was done by myself with some additional comments about a bug being reported by people on GDN. It did spend a few hours on it ;-)



    I tried using the tamest verbiage I could find while at the same time making me perspective on the subject as plain as possible ;-)



    Again, thanks for the update and sorry that you ended up being the example in this particular case... but hopefully others will take note and see that this is a problem that is bigger than just one example.



    Also, I'll update my entry stating that you made good ;-)

  • Justice, this was a misunderstanding and I have addressed it with Cory. I assumed the code came staight from the SDK, thus no link to Cory. A link has since been added. If you look through my past blogs you will see that I do give credit to those that have helped along the way.

  • Anonymous, sees Cory's link on the mazimize, minimize issue.



  • Thanks for the help.

  • but the alt+f4 closed the form. ???

  • Try this code (my forms inherits from this):
    It solves maximize/minimize and "alt+f4" problems
    The inherited forms have the new "CloseEnable" property

    Public Class FormEnabClose
    #Region " Declare "
    Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Integer, ByVal revert As Integer) As Integer
    Private Declare Function EnableMenuItem Lib "user32" (ByVal menu As Integer, ByVal ideEnableItem As Integer, ByVal enable As Integer) As Integer
    #End Region

    #Region " Const "
    Private Const SC_CLOSE As Integer = &HF060
    Private Const MF_BYCOMMAND As Integer = &H0
    Private Const MF_GRAYED As Integer = &H1
    Private Const MF_ENABLED As Integer = &H0
    #End Region

    #Region " Var "
    Protected mWinStateAnt As FormWindowState
    Protected mCloseDisable As Boolean
    #End Region

    #Region " Prop "
    Public Property CloseEnable() As Boolean
    Get
    Return Not mCloseDisable
    End Get
    Set(ByVal value As Boolean)
    mCloseDisable = Not value
    mWinStateAnt = Me.WindowState
    RefreshCloseButton()
    End Set
    End Property
    #End Region

    #Region " Meth "
    Public Sub DisableFormCloseButton()
    ' The return value specifies the previous state of the menu item (it is either
    ' MF_ENABLED or MF_GRAYED). 0xFFFFFFFF indicates that the menu item does not exist.
    Select Case EnableMenuItem(GetSystemMenu(Me.Handle.ToInt32, 0), SC_CLOSE, MF_BYCOMMAND Or MF_GRAYED)
    Case MF_ENABLED
    Case MF_GRAYED
    Case &HFFFFFFFF
    Throw New Exception("The Close menu item does not exist.")
    Case Else
    End Select
    End Sub

    Public Sub EnableFormCloseButton()
    EnableMenuItem(GetSystemMenu(Me.Handle.ToInt32, 0), SC_CLOSE, MF_BYCOMMAND)
    End Sub

    Public Sub RefreshCloseButton()
    If CloseEnable Then EnableFormCloseButton() Else DisableFormCloseButton()
    End Sub

    Private Sub FormEnabClose_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
    If mWinStateAnt = Me.WindowState Then Exit Sub
    RefreshCloseButton()
    mWinStateAnt = Me.WindowState
    End Sub

    Private Sub FormEnabClose_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
    If Not CloseEnable Then
    e.Cancel = True
    Exit Sub
    End If
    End Sub
    #End Region
    End Class

  • @iluvatarm> Sir thanks for your post. i've got some useful information regarding bypass close event.

    here are some novice example.
    This code works with Visual Basic.NET 2008
    VB.NET>WPF Window

    Private Sub frmYourFormName_Unloaded(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
    e.Cancel = True
    End Sub

    I Hope it will help others. lolz
    thanks and best regards

    -mccabero

Comments have been disabled for this content.