Het kan soms gewenst zijn om in Excel of Word de afsluitknop [X] op een formulier uit te schakelen. Bijvoorbeeld bij een formulier waar de gebruiker altijd iets moet invullen voordat deze afgesloten mag worden of bij een formulier met een voortgangsbalk. Ook kunnen er esthetische redenen zijn om de afsluitknop te verbergen.
Wat in de praktijk vaak gebeurt is om de werking van de sluitknop uit te schakelen met behulp van de UserForm_QueryClose gebeurtenis. Dat kan bijvoorbeeld als volgt:
Private Sub Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
Cancel = True
MsgBox "De afsluitknop [X] is uitgeschakeld.", vbCritical, "Afsluitknop uitgeschakeld"
End If
End Sub
Dit werkt op zich wel maar qua gebruikerservaring is dit natuurlijk niet best. Gebruikers klikken op de sluitknop en krijgen vervolgens de melding dat dat niet kan. Beter is dan om de sluitknop helemaal te verbergen zodat gebruikers niet de mogelijkheid hebben om tevergeefs op de sluitknop te klikken.
Standaard kan in een formulier de sluitknop niet uitgeschakeld worden, maar met behulp van Windows API aanroepen is dat wel mogelijk. Zet daartoe onderstaande code in een aparte module:
Private Const GWL_STYLE As Long = -16
Private Const WS_SYSMENU As Long = &H80000
#If VBA7 Then
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#If Win64 Then
Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
#Else
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#End If
Public Sub RemoveCloseButton(frm As Object)
#If VBA7 Then
Dim lStyle As LongPtr, lFrmHandle As LongPtr
#Else
Dim lStyle As Long, lFrmHandle As Long
#End If
lFrmHandle = FindWindow("ThunderDFrame", frm.Caption)
lStyle = GetWindowLong(lFrmHandle, GWL_STYLE)
lStyle = lStyle And Not WS_SYSMENU
SetWindowLong lFrmHandle, GWL_STYLE, lStyle
End Sub
Dit kan in een formulier gebruikt worden in het UserForm_Initialize of UserForm_Activate gebeurtenis:
Private Sub UserForm_Initialize()
RemoveCloseButton Me
End Sub
Als, tijdens het openen van een formulier, de caption (opschrift) van het formulier met behulp van VBA dynamisch gewijzigd wordt, dan moet deze aanroep na deze wijziging geplaatst worden.
Let er op dat op het formulier een button aanwezig is waarmee het formulier afgesloten kan worden, voordat de sluitknop verborgen wordt. Anders kan namelijk het formulier niet meer afgesloten worden!
Deze code werkt alleen in Windows en werkt ook in 64 bits Office versies.
Vragen / suggesties
Hopelijk heeft dit artikel geholpen bij het verwijderen van de afsluitknop op een VBA formulier. Als er verdere vragen over dit onderwerp zijn of suggesties voor verbetering, plaats dan een reactie hieronder.