Full Version: Hide the [X] Close Button in Access 2007
UtterAccess Discussion Forums > Access Knowledge Center > Access Code Archive
dbtech1
There are a lot of different ways that you can hide the [X] Close Button in Access, but most of the ways that work in Access 2000 and Access 2003 do NOT work in Access 2007.
After a lot of searching and testing, I was able to find one that does in fact work with Access 2007 and wanted to share it with everyone.
CODE
'TO DISABLE THE ACCESS [X] BUTTON, RUN THE FOLLOWING
     Call ShowAccessCloseButton(False)
  
  
'TO ENABLE THE ACCESS [X] BUTTON, RUN THE FOLLOWING
     Call ShowAccessCloseButton(True)

CODE
Option Compare Database
  
Option Explicit
  
Private Const GWL_STYLE = (-16)
Private Const WS_CAPTION = &HC00000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_SYSMENU = &H80000
  
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOZORDER = &H4
Public Const SWP_FRAMECHANGED = &H20
  
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
  
Private Declare Function SetWindowPos Lib "user32" ( _
    ByVal hwnd As Long, _
    ByVal hWndInsertAfter As Long, _
    ByVal X As Long, _
    ByVal Y As Long, _
    ByVal cx As Long, _
    ByVal cy As Long, _
    ByVal wFlags As Long _
    ) As Long
  
  
Function ShowAccessCloseButton(Show As Boolean) As Long
  
  Dim hwnd As Long
  Dim nIndex As Long
  Dim dwNewLong As Long
  Dim dwLong As Long
  
  hwnd = hWndAccessApp
  nIndex = GWL_STYLE
  
  Const wFlags = SWP_NOSIZE + SWP_NOZORDER + SWP_FRAMECHANGED + SWP_NOMOVE
  Const FLAGS_COMBI = WS_MINIMIZEBOX Or WS_MAXIMIZEBOX Or WS_SYSMENU
  
  dwLong = GetWindowLong(hwnd, nIndex)
  
  If Show Then
    dwNewLong = (dwLong Or FLAGS_COMBI)
  Else
    dwNewLong = (dwLong And Not FLAGS_COMBI)
  End If
  
  Call SetWindowLong(hwnd, nIndex, dwNewLong)
  Call SetWindowPos(hwnd, 0&, 0&, 0&, 0&, 0&, wFlags)
  
End Function
JessicaZ
Hi there
The code is hiding the minimize button rather than the close button for me...any thoughts?
tonez90
Hi I use the following and it appears to work in 2007 (unsure about 2010 as I dont have it). I hope this helps
Private Const GWL_STYLE = (-16)
Private Const WS_CAPTION = &HC00000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_SYSMENU = &H80000
Const MF_BYCOMMAND = &H0&
Const MF_DISABLED = &H2&
Const MF_ENABLED = &H0&
Const MF_GRAYED = &H1&
Const SC_CLOSE = &HF060&
Private Declare Function apiEnableMenuItem Lib "User32" Alias "EnableMenuItem" (ByVal hMenu As Long, ByVal wIDEnableMenuItem As Long, ByVal wEnable As Long) As Long
Private Declare Function apiGetSystemMenu Lib "User32" Alias "GetSystemMenu" (ByVal hWnd As Long, ByVal Flag As Long) As Long
Function DisableAccessCloseButton(bEnable As Boolean, Optional ByVal lhWndTarget As Long = 0) As Long
On Error GoTo Handle_Error
'DisableAccessCloseButton(True) turns on the X close button
'DisableAccessCloseButton(False) turns off the X close button
Dim lhWndMenu As Long, lReturnVal As Long, lAction As Long
lhWndMenu = apiGetSystemMenu(iif(lhWndTarget = 0, Application.hWndAccessApp, lhWndTarget), False)
If lhWndMenu <> 0 Then
If bEnable Then
lAction = MF_BYCOMMAND Or MF_ENABLED
Else
lAction = MF_BYCOMMAND Or MF_DISABLED Or MF_GRAYED
End If
lReturnVal = apiEnableMenuItem(lhWndMenu, SC_CLOSE, lAction)
End If
DisableAccessCloseButton = lReturnVal
Exit_Process:
Exit Function

Handle_Error:
msgbox("Error: " & err.number & vbcrlf & errdescription
Resume Exit_Process

End Function
CyberCow
Instead of determining if the "X" is clicked, or trying to hide it altogether, I take a more proactive and less code intensive approach and PREVENT the "X" from being activated by setting the Main Menu form's (or if you don't have/use a switchboard or main menu - a hidden form will do) 'OnUnload' event procedure to evaluate the the state of a global boolean variable I named "myOKtoClose".
Create a global boolean variable named (say): "myOKtoClose"
FOr set a TempVars up like so:
TempVars.Add "myOKtoClose", False
(TempVars only work in Access 2007 & up)
At app start up, "myOKtoClose" is set to false (if you use Tempvars - it's done like above) and the main menu form (which is open during the entire session - either open, hidden or minimized at the client's discretion) has the following line in the OnUnload event (in VBA):
If Not myOKtoClose Then Cancel = True
If using TempVars: If TempVars!myOKtoClose Then Cancel = True
This prevents the form from closing, effectively disabling the user's ability to close Access by clicking on the 'X'.
To allow the main menu form to close, I place a command button that says "Quit Application" in its caption and set the following 'OnClick' event in VBA:
CODE
myOKtoClose = True
' Tempvars.Add "myOKtoClose", True
DoCmd.Quit

The above (without the Tempvars) works in all versions of Access. The TempVars portions only work in Access 2007 and up. They are demonstrated because a TempVar will not loose it's value if the system errors. A Global variable can loose it's contents on a system error.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.