0

I am maintaining several old Microsoft Access Databases and I use the following to stop users from exiting the application except from the menus. For whatever reason the unload event has never done the job properly so this is what we use:

Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, _
    ByVal bRevert As Long) As Long

Private Declare Function EnableMenuItem Lib "user32" (ByVal hMenu As _
    Long, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long

Const MF_GRAYED = &H1&
Const MF_BYCOMMAND = &H0&
Const SC_CLOSE = &HF060&

Public Function SetEnabledState(blnState As Boolean)
    Call CloseButtonState(blnState)
   
End Function

'Disable the Close Button Option
Sub CloseButtonState(boolClose As Boolean)
    Dim hWnd As Long
    Dim wFlags As Long
    Dim hMenu As Long
    Dim result As Long
      
    hWnd = Application.hWndAccessApp
    hMenu = GetSystemMenu(hWnd, 0)
    If Not boolClose Then
        wFlags = MF_BYCOMMAND Or MF_GRAYED
    Else
        wFlags = MF_BYCOMMAND And Not MF_GRAYED
    End If
   
    result = EnableMenuItem(hMenu, SC_CLOSE, wFlags)
End Sub

Unfortunately some users have have been updated to 64-bit versions of office and "user32" is not recognised. Is there a way I could recode this for both 64-bit and 32-bit?

LeasMaps
  • 300
  • 4
  • 14

2 Answers2

1

You should do this with conditional compilation, see for example here: How should I make my VBA code compatible with 64-bit Windows?.

To get the correct declarations for you API calls, read my answer https://stackoverflow.com/a/76362787/7599798 - I use a tool "Windows API Viewer" but it is a little bit tricky nowadays to find it.

The following code should work on 32bit and 64bit, however, I have tested it only on 64bit (have no more 32bit available)

#If VBA7 Then
Private Declare PtrSafe Function GetSystemMenu Lib "user32" ( _
    ByVal hWnd As LongPtr, ByVal bRevert As Long) As LongPtr

Private Declare PtrSafe Function EnableMenuItem Lib "user32" ( _
    ByVal hMenu As LongPtr, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long

#Else
private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, _
    ByVal bRevert As Long) As Long

Private Declare Function EnableMenuItem Lib "user32" (ByVal hMenu As _
    Long, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long
#End If

Const MF_GRAYED = &H1&
Const MF_BYCOMMAND = &H0&
Const SC_CLOSE = &HF060&

Public Function SetEnabledState(blnState As Boolean)
    Call CloseButtonState(blnState)
End Function

'Disable the Close Button Option
Sub CloseButtonState(boolClose As Boolean)
    
#If VBA7 Then
    Dim hMenu As LongPtr
#Else
    Dim hMenu As Long
#End If
    Dim hWnd As Long
    Dim wFlags As Long
    Dim result As Long

    hWnd = Application.hWndAccessApp
    hMenu = GetSystemMenu(hWnd, 0)
    If Not boolClose Then
        wFlags = MF_BYCOMMAND Or MF_GRAYED
    Else
        wFlags = MF_BYCOMMAND And Not MF_GRAYED
    End If
   
    result = EnableMenuItem(hMenu, SC_CLOSE, wFlags)
End Sub
FunThomas
  • 23,043
  • 3
  • 18
  • 34
  • Since Access 2007 and earlier are unsupported for over 5 years (https://learn.microsoft.com/en-us/lifecycle/products/microsoft-office-access-2007) there's no need for conditional compilation to accommodate them IMO, and we can just assume VBA7 – Erik A Jun 16 '23 at 10:01
  • Works nicely on 32-bit office. Thanks Mate – LeasMaps Jun 19 '23 at 01:15
0

Try with the 64-bit declarations:

Private PtrSafe Declare Function GetSystemMenu Lib "user32" ( _
    ByVal hWnd As LongPtr, ByVal bRevert As Long) As LongPtr

Private PtrSafe Declare Function EnableMenuItem Lib "user32" ( _
    ByVal hMenu As LongPtr, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long

and adjust the rest of the code accordingly.

Gustav
  • 53,498
  • 7
  • 29
  • 55
  • I'm guessing I would have to upgrade my office environment to 64-bit to do this? I'm wondering if I should just tell the user to get the 'IT people' to re-install the 32-bit version. – LeasMaps Jun 16 '23 at 07:04
  • That should not be necessary. And, instead of re-installing 32-bit, you should rather install 64-bit all over. – Gustav Jun 16 '23 at 07:44
  • Hi Gustav - I have no control over what is installed on the Users pc's (we have around 30 users) or whether they even have PC's compatible with 64-bit office unfortunately. This only came up as one user had his laptop upgraded. – LeasMaps Jun 17 '23 at 08:49