Search code examples
vbams-access32bit-64bit

Equivalent to "User32" in 64-bit MSAccess


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?


Solution

  • 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