A
VB developer may find themselves developing an application who's integrity is crucial, and therefore must prevent the user from accidentally
terminating the application during its life, while still displaying the system menu. And while Visual Basic does provide two places to cancel
an impending close - the QueryUnload and Unload subs - such a sensitive application may need to totally prevent even activation of the
shutdown.
Although it is not possible to simply disable the Close button while
the Close system menu option is present, just a few lines of API code will remove the system menu Close option and in doing so permanently
disable the title bar close button. |
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
' applications, but you may not reproduce
' or publish this code on any web site,
' online service, or distribute as source
' on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Const MF_BYPOSITION = &H400
Private Const MF_REMOVE = &H1000
Private Declare Function DrawMenuBar Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" _
(ByVal hMenu As Long) As Long
Private Declare Function GetSystemMenu Lib "user32" _
(ByVal hwnd As Long, _
ByVal bRevert As Long) As Long
Private Declare Function RemoveMenu Lib "user32" _
(ByVal hMenu As Long, _
ByVal nPosition As Long, _
ByVal wFlags As Long) As Long
Private Sub Form_Load()
Dim hMenu As Long
Dim menuItemCount As Long
'Obtain the handle to the form's system menu
hMenu = GetSystemMenu(Me.hwnd, 0)
If hMenu Then
'Obtain the number of items in the menu
menuItemCount = GetMenuItemCount(hMenu)
'Remove the system menu Close menu item.
'The menu item is 0-based, so the last
'item on the menu is menuItemCount - 1
Call RemoveMenu(hMenu, menuItemCount - 1, _
MF_REMOVE Or MF_BYPOSITION)
'Remove the system menu separator line
Call RemoveMenu(hMenu, menuItemCount - 2, _
MF_REMOVE Or MF_BYPOSITION)
'Force a redraw of the menu. This
'refreshes the titlebar, dimming the X
Call DrawMenuBar(Me.hwnd)
End If
End Sub |
For completeness, you may want to confirm that the
menuItemCount matches the value you expect before performing the removal. For example, on a normal form with a full system menu,
menuItemCount will return seven. Because the method above removes the last two items from the menu, repeated calling will eventually remove
all the system menu items.
But what if you're developing a MDI app, and you want to disable the
close button on the parent form, any child form, or any non-MDI form spawned from that app? Then you want the alternative method -
Killing Any Form's Close Menu
Option and 'X' Button -
SDI, MDIParent or MDIChild |