Visual Basic Window/Form Routines
RemoveMenu: Killing the Form's Close Menu and 'X' Button
Posted:   Wednesday July 8, 1998
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB5, Windows 98
OS restrictions:   None
Author:   VBnet - Randy Birch


Killing Any Form's Close Menu Option and 'X' Button - SDI, MDIParent or MDIChild


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.

 BAS Module Code

 Form Code
Add the following to a form - shown here is the code to disable the X called from the form's Load sub:

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


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter