Solved

Disabling Close Command

Posted on 2008-06-26
7
368 Views
Last Modified: 2012-06-27
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

0
Comment
Question by:bejhan
  • 4
  • 2
7 Comments
 
LVL 27

Expert Comment

by:jjafferr
ID: 21876409
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

0
 
LVL 1

Author Comment

by:bejhan
ID: 21876477
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.
0
 
LVL 75

Accepted Solution

by:
DatabaseMX (Joe Anderson - Access MVP) earned 500 total points
ID: 21876500
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 1

Author Comment

by:bejhan
ID: 21876641
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.
0
 
LVL 1

Author Comment

by:bejhan
ID: 21876843
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?
0
 
LVL 75
ID: 21877177
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
0
 
LVL 1

Author Comment

by:bejhan
ID: 21877210
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.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

When you are entering numbers in a speadsheet, and don't remember what 6×7 is, you just type “=6*7" instead. It works in every cell! This is not so in Access. To enter the elusive 42 in a text box, you have to find a calculator, and then copy the re…
In the article entitled Working with Objects – Part 1 (http://www.experts-exchange.com/Microsoft/Development/MS_Access/A_4942-Working-with-Objects-Part-1.html), you learned the basics of working with objects, properties, methods, and events. In Work…
Familiarize people with the process of utilizing SQL Server stored procedures from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Micr…
Using Microsoft Access, learn some simple rules for how to construct tables in a relational database. Split up all multi-value fields into single values: Split up fields that belong to other things into separate tables: Make sure that all record…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now