Link to home
Start Free TrialLog in
Avatar of bejhan
bejhan

asked on

Disabling Close Command

I found a Microsoft article of how to disable the MS Access top close button and the close option in the system menu (when you right click on MS Access entry on the Windows task bar). I modified it to be very simple and it works great when only one form is open. However, when two forms open there is no longer a single MS Access entry on the WIndows task bar, there are individual entries for each form. So of course the close option in the system menu is enabled again as these are not the MS Access entry. So to get around this I figured I could just disable the close option in the new task bar. Easier said than done however.

For the function to disable the MS Access window's top close button and system menu close option I use Application.hWndAccessApp. When I attempted to disable the individual form window's closing stuff I used Me.hwnd for the argument from within the form. Using Me.Hwnd disabled the forms top close button but not the system menu close option.

What am I doing wrong?
Option Compare Database
Option Explicit
 
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 DisableClose(hWnd As Long)
    Dim wFlags As Long
    Dim hMenu As Long
    
    hMenu = GetSystemMenu(hWnd, 0)
    wFlags = MF_BYCOMMAND Or MF_GRAYED
    
    EnableMenuItem hMenu, SC_CLOSE, wFlags
End Function

Open in new window

Avatar of jjafferr
jjafferr
Flag of Oman image

put the code in a module,

On the Main Form's load, have this call:
    'hide the close button
    HideAccessCloseButton

On the main Form's Close, have this call:
    'restore the max, min, close buttons
    UnHideAccessCloseButton

jaffer
Option Compare Database 

    Private Const GWL_EXSTYLE = (-20)
    Private Const GWL_STYLE = (-16) 
    Private Const WS_MAXIMIZEBOX = &H10000
    Private Const WS_MINIMIZEBOX = &H20000
    Private Const WS_SYSMENU = &H80000 
    Private Const HWND_TOP = 0
    Private Const SWP_NOMOVE = &H2
    Private Const SWP_NOSIZE = &H1
    Private Const SWP_FRAMECHANGED = &H20
    Private Const SWP_DRAWFRAME = SWP_FRAMECHANGED 
    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 GetWindowLong Lib "user32" _
    Alias "GetWindowLongA" (ByVal hWnd As Long, _
    ByVal nIndex 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 
    Sub HideAccessCloseButton() 
        Dim lngStyle As Long 
        lngStyle = GetWindowLong(hWndAccessApp, GWL_STYLE)
        lngStyle = lngStyle And Not WS_SYSMENU
        Call SetWindowLong(hWndAccessApp, GWL_STYLE, lngStyle)
        Call SetWindowPos(hWndAccessApp, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_DRAWFRAME) 
    End Sub 
    Sub UnHideAccessCloseButton() 
        Dim lngStyle As Long 
        lngStyle = GetWindowLong(hWndAccessApp, GWL_STYLE)
        lngStyle = lngStyle Or WS_SYSMENU
        Call SetWindowLong(hWndAccessApp, GWL_STYLE, lngStyle)
        Call SetWindowPos(hWndAccessApp, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_DRAWFRAME) 
    End Sub

Open in new window

Avatar of bejhan
bejhan

ASKER

I don't think you understood my problem. I can disable and enable the access close button and system menu close option (SMCO). That is not problem.

For example:
I open form1, disable access close stuff. So now I can't exit the application unless I use the exit button provided in my form which is exactly what I want. Now I open form2. Form1 is still open. Now instead of the MS Access entry being the taskbar there is an entry for form1 and for form2. Since I only disabled the SMCO for the MS Access window, form1 and form2 can still be closed via their own SMCO. I want to disable form1's and form2's SMCO. So I try to use the same function I disabled the access top close button and SMCO except with form1.hwnd and form2.hwnd as arguments to the function. Now form1's and form2's top close button is disabled but their SMCOs are still enabled. I want to disable these SMCOs.
ASKER CERTIFIED SOLUTION
Avatar of DatabaseMX (Joe Anderson - Former Microsoft Access MVP)
DatabaseMX (Joe Anderson - Former Microsoft Access MVP)
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bejhan

ASKER

Wow, so simple... so simple. Thank you MX I have been grappling this problem for about a month now. Even had to close a question and ask again because I didn't find any answers. Incase anyone was wondering this is all I did (following the guidance of the link posted):

Declared Public pboolCloseAccess As Boolean in a module.

Created a hidden form, that loaded before any other forms.

In the hidden form I put these two events:

Private Sub Form_Load()
pboolCloseAccess = False
End Sub

Private Sub Form_Unload(Cancel As Integer)
Cancel = False

If Not pboolCloseAccess Then Cancel = True
End Sub

So this way, my exit command would set pboolCloseAccess to True so that the hidden form would unload, otherwise Cancel = True and it stops the whole process.
Avatar of bejhan

ASKER

I just realized that doesn't stop the user from closing a form while in the middle of work which is my main concern. I suppose I could use the same concept but for each form? Any better ideas?
Well, you can keep a form from close by using the UnLoad event like so:

Private Sub Form_UnLoad(Cancel As Integer)

    If <SomeCondition> =True Then
       Msgbox "Some message"
       Cancel = True
    End If

End Sub
Avatar of bejhan

ASKER

That's what I was thinking of doing but that is alot of work. I guess if its the only way I'll have to do it.