Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Disabling close button 4

Status
Not open for further replies.

WoundEdGoat

Programmer
May 10, 2002
39
0
0
CA
Can someone tell me how to disable the close button on a form and still have the use of the minimize button?
 
This has been discussed many a time on this forum, however for the sake of ease:

'*----------------------------------------------------------*
'* Name : DisableX *
'*----------------------------------------------------------*
'* Purpose : Disables the close button ('X') on form. *
'*----------------------------------------------------------*
'* Parameters : frm Required. Form to disable 'X'-button *
'*----------------------------------------------------------*
'* Description: This function disables the X-button on a *
'* : form, to keep the user from closing a form *
'* : that way, but keeps the min & max buttons. *
'*----------------------------------------------------------*
Public Function DisableX(frm As Form)
Dim hMenu As Long, nCount As Long

'Get handle to system menu
hMenu = GetSystemMenu(frm.hwnd, 0)

'Get number of items in menu
nCount = GetMenuItemCount(hMenu)

'Remove last item from system menu (last item is 'Close')
Call RemoveMenu(hMenu, nCount - 1, MF_DISABLED Or MF_BYPOSITION)

'Redraw menu
DrawMenuBar frm.hwnd

End Function


And then you call it like this

DisableX me
 
Hey WoundEdGoat,
Although I'm sure the above code works there is an even easier way (if fact it's a one-liner).

Just type in Form_Unload:

Cancel = 1

Tell me how it works... lol.

-Jason
 
Um...SilverElectron..in your example the form will never unload.
 
Um...rorubin..yes it will. Providing you say Cancel = 0 before you want the window to close.
 
Can you illustrate the way you proposed it. You said add one line cancel = 1 in the form unload. Can you explain to me what you mean when you say Cancel = 0.

Thanks.
 
The only way I see it is if you set your 1 to a variable and set it to 1 and 0 before you unload it? Am I understanding what you are saying.
 
while its not essential... here a some API calls needed for rorubins solution.

Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) As Long

Const MF_DISABLED = &H2&
Const MF_BYPOSITION = &H400&

i favour rorubins answer because i dont like the idea of having the close button work, but not work... i personally would think the program wasnt working properly!

just an opinion!

If somethings hard to do, its not worth doing - Homer Simpson
 
ADoozer - Your right sorry I forgot to Declare the external functions.
 
Another way (even thought the close button is still visible and not greyed out) would be to simply code:

If UnloadMode = vbFormControlMenu Then Cancel = True

Or, even more simple:

Cancel = UnloadMode = vbFormControlMenu
 
rorubin - very impressive!

I there a way to enable the 'x' once it has been disabled?

I have some code running that I don't want the user to be able to 'close' out of while it's running, however I would like them to be able to close using the 'x' after my code finishes.

THanks for your help!!
 
Try this ...
Code:
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    If Not MyCodeIsDone Then
    	If UnloadMode = 0 Then Cancel = True
    End If
End Sub
This allows the form to be closed programatically (UnloadMode = 1)
 
jbradley: this still leaves the x looking enabled making the user think the app has hung (especially if the code being run is lengthy)

DonPeters: have a look into insertmenu or insertmenuitem API's. to get the menuiteminfo for the x button, you can use the getmenuiteminfo in the disableX call before you removemenu.

good luck!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
File Formats Galore @
 
donpeters:

here you go...
Code:
Private Declare Function GetSystemMenu Lib "user32" ( _
    ByVal hwnd As Long, _
    ByVal bRevert As Long _
) As Long

Private Declare Function GetMenuItemCount Lib "user32" ( _
    ByVal hMenu As Long _
) As Long

Private Declare Function RemoveMenu Lib "user32" ( _
    ByVal hMenu As Long, _
    ByVal nPosition As Long, _
    ByVal wFlags As Long _
) As Long

Private Declare Function DrawMenuBar Lib "user32" ( _
    ByVal hwnd As Long _
) As Long

Private Declare Function InsertMenuItem Lib "user32" _
    Alias "InsertMenuItemA" ( _
        ByVal hMenu As Long, _
        ByVal un As Long, _
        ByVal bool As Boolean, _
        ByRef lpcMenuItemInfo As MENUITEMINFO _
) As Long

Private Const MF_DISABLED = &H2&
Private Const MF_BYPOSITION = &H400&
Private Const SC_CLOSE = &HF060&

Private Type MENUITEMINFO
    cbSize As Long
    fMask As Long
    fType As Long
    fState As Long
    wID As Long
    hSubMenu As Long
    hbmpChecked As Long
    hbmpUnchecked As Long
    dwItemData As Long
    dwTypeData As String
    cch As Long
End Type


Private Sub Command1_Click()
    DisableX Me
End Sub

Private Sub Command2_Click()
    EnableX Me
End Sub

Private Function EnableX(frm As Form)
    
    Dim hMenu As Long, TempMenu As MENUITEMINFO
    
    'get handle again
    hMenu = GetSystemMenu(frm.hwnd, 1)
    
    'replace close button
    InsertMenuItem hMenu, SC_CLOSE, 0, TempMenu
    
    'redraw menu
    DrawMenuBar frm.hwnd
    
End Function

Public Function DisableX(frm As Form)
  Dim hMenu As Long, nCount As Long

  'Get handle to system menu
  hMenu = GetSystemMenu(frm.hwnd, 0)

  'Get number of items in menu
  nCount = GetMenuItemCount(hMenu)
  
  'Remove last item from system menu (last item is 'Close')
  Call RemoveMenu(hMenu, nCount - 1, MF_DISABLED Or MF_BYPOSITION)

  'Redraw menu
  DrawMenuBar frm.hwnd

End Function
good luck!!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
File Formats Galore @
 
Thanks!!

I also found this on - a great site I might add...

Pay particular attention to the bRevert parameter - a couple of simple lines...

Dim retVal As Long

retVal = GetSystemMenu(frm.hwnd, 1)

and the menu is set back to default which worked to solve my problem.

I do appreciate the code though - as I have other places I can use it!!

GetSystemMenu
The GetSystemMenu function allows the application to access the window menu (also known as the System menu or the Control menu) for copying and modifying.

VB4-32,5,6
Declare Function GetSystemMenu Lib "user32" Alias "GetSystemMenu" (ByVal hwnd As Long, ByVal bRevert As Long) As Long

Operating Systems Supported

Requires Windows NT 3.1 or later; Requires Windows 95 or later


Library

User32


Parameter Information

· hWnd
Identifies the window that will own a copy of the window menu.

· bRevert
Specifies the action to be taken. If this parameter is FALSE, GetSystemMenu returns the handle of the copy of the window menu currently in use. The copy is initially identical to the window menu, but it can be modified.
If this parameter is TRUE, GetSystemMenu resets the window menu back to the Windows default state. The previous window menu, if any, is destroyed.


Return Values

If the bRevert parameter is FALSE, the return value is the handle of a copy of the window menu. If the bRevert parameter is TRUE, the return value is NULL.


Examples

- Remove Menu
- TrackPopupMenu
- Disable Resize



Related Functions

- GetMenuItemCount
- RemoveMenu
 
If UnloadMode = vbFormControlMenu Then
Cancel = True
End If
This is easy
hb
 
donpeters: yeah i realised i went over the top on code after i posted, o well not to worry!!

baileyhp: this is exactly what VBOldTimer said last month!!!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
File Formats Galore @
 
Thanks ADoozer . . .

(c:

Please pardon the grammar.
Not good in english.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top