Hide close [X] button on excel vba userform for my progress bar

限于喜欢 提交于 2019-12-03 07:34:50

问题


I created a userform to show a progress bar when the macro is still importing sheets

The problem is the user can press the red [X] button that will close and interrupt the processing done.

Is there a way to hide this red button of doom so that potential users don't have any confusing buttons to click while it runs.

edit:

I have tried this

'Find the userform's Window
Private Declare Function FindWindow Lib "user32" _
        Alias "FindWindowA" ( _
        ByVal lpClassName As String, _
        ByVal lpWindowName As String) As Long

'Get the current window style
Private Declare Function GetWindowLong Lib "user32" _
        Alias "GetWindowLongA" ( _
        ByVal hWnd As Long, _
        ByVal nIndex As Long) As Long

'Set the new window style
Private Declare Function SetWindowLong Lib "user32" _
        Alias "SetWindowLongA" ( _
        ByVal hWnd As Long, _
        ByVal nIndex As Long, _
        ByVal dwNewLong As Long) As Long

Const GWL_STYLE = -16
Const WS_SYSMENU = &H80000

and I used this on userform_initialize

   Dim hWnd As Long, lStyle As Long

   'Which type of userform
   If Val(Application.Version) >= 9 Then
      hWnd = FindWindow("ThunderDFrame", Me.Caption)
   Else
      hWnd = FindWindow("ThunderXFrame", Me.Caption)
   End If

   'Get the current window style and turn off the Close button
   lStyle = GetWindowLong(hWnd, GWL_STYLE)
   SetWindowLong hWnd, GWL_STYLE, (lStyle And Not WS_SYSMENU)

I am getting this error message

this code was taken from here. I don't know what I'm doing wrong and I already removed the comments. This is the simplest code that I found so I would like to integrate it to my userform. Any help is appreciated.


回答1:


Below is a routine that you can call like this:

subRemoveCloseButton MyForm

or from within your form:

subRemoveCloseButton Me 

Here's the code you'll need:

Private Const mcGWL_STYLE = (-16)
Private Const mcWS_SYSMENU = &H80000

'Windows API calls to handle windows
#If VBA7 Then
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#Else
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If

#If VBA7 Then
    Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
#Else
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
#End If

#If VBA7 Then
    Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#Else
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#End If


Public Sub subRemoveCloseButton(frm As Object)
    Dim lngStyle As Long
    Dim lngHWnd As Long

    lngHWnd = FindWindow(vbNullString, frm.Caption)
    lngStyle = GetWindowLong(lngHWnd, mcGWL_STYLE)

    If lngStyle And mcWS_SYSMENU > 0 Then
        SetWindowLong lngHWnd, mcGWL_STYLE, (lngStyle And Not mcWS_SYSMENU)
    End If

End Sub



回答2:


You can work it out from the following snippets:

Select the cmdClose button On the Menu bar, choose View | Code Where the cursor is flashing, enter the following code:

Private Sub cmdClose_Click()
  Unload Me
End Sub

On the Menu bar, choose View | Object, to return to the UserForm.

To allow users to close the form by pressing the Esc key:

Select the cmdClose button In the Properties window, change the Cancel property to True

To prevent users from closing the form by clicking the X button

When the UserForm is opened, there is an X at the top right. In addition to using the Close Form button, people will be able to close the form by using the X. If you want to prevent that, follow these steps.

Right-click on an empty part of the UserForm Choose View | Code From the Procedure dropdown, at the top right, choose QueryClose

Where the cursor is flashing, paste the highlighted code from the following sample

Private Sub UserForm_QueryClose(Cancel As Integer, _
  CloseMode As Integer)
  If CloseMode = vbFormControlMenu Then
    Cancel = True
    MsgBox "Please use the Close Form button!"
  End If
End Sub

On the Menu bar, choose View | Object, to return to the UserForm. Now, if someone clicks the X in the UserForm, they'll see your message.

from http://www.contextures.com/xlUserForm01.html




回答3:


This is an improvement of the above answer of @Peter Albert

  • Windows API calls are now Office x64 safe
  • FindWindow call was improved to find Excel UserForms only. The function in the original answer searches every window class (e.g. Explorer windows and other program's windows). Therefore it could happen that the [x] button of other programs or explorer windows have been removed when their name was the same name as the UserForm.

Private Const mcGWL_STYLE = (-16)
Private Const mcWS_SYSMENU = &H80000

'Windows API calls to handle windows
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
    ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr

#If Win64 Then
    Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" ( _
        ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" ( _
        ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
    Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" ( _
        ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" ( _
        ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If

Public Sub RemoveCloseButton(objForm As Object)
    Dim lngStyle As LongPtr
    Dim lngHWnd As LongPtr

    Dim lpClassName As String
    lpClassName = vbNullString
    If Val(Application.Version) >= 9 Then
       lpClassName = "ThunderDFrame"
    Else
       lpClassName = "ThunderXFrame"
    End If

    lngHWnd = FindWindow(lpClassName, objForm.Caption)
    lngStyle = GetWindowLongPtr(lngHWnd, mcGWL_STYLE)

    If lngStyle And mcWS_SYSMENU > 0 Then
        SetWindowLongPtr lngHWnd, mcGWL_STYLE, (lngStyle And Not mcWS_SYSMENU)
    End If
End Sub

ThunderDFrame?
The UserForms in Excel are actually of the Windows class ThunderDFrame, which is the class for all UserFroms in Microsoft Office applications after 2002. Before that, it was ThunderXFrame.




回答4:


Ask the user if they want to close the form - and lose edits (say). Based on ideas from Justin & Peter.

Private Sub UserForm_QueryClose(Cancel As Integer, _
                            CloseMode As Integer)
Dim ans
If CloseMode = vbFormControlMenu Then
    Cancel = True
    ans = Msgbox("Cancel edit?", vbQuestion + vbYesNo)
    If ans = vbYes Then
       Me.Hide
    End if
End If
End Sub

Edit: Actually I realise this is a bit off topic as OP wanted to remove the X option - but still I find this handy for interactive forms.




回答5:


I know this is an old question, but for the type of user form the OP cited, you don't have to remove, hide or disable the close button. There is a much simpler way ;)

For any user form which does not have any elements which the user interacts with (buttons etc) and which will close itself when it has finished its purpose, simply disabling the form is fine.

To disable the user form: In the user form's properties, against Enabled set False. The user form will show until it's code tells it to hide. The user will not be able to do anything to the form (cannot close, cannot move etc).

Note also that whether you want the user to be able to do anything else in the main window while the user form is still showing decides whether you set ShowModal.




回答6:


A useful way to disable the button is to do the following:

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = 0 Then Cancel = True
End Sub

Although this doesn't get rid of the button, but it does make clicking on it accomplish nothing.



来源:https://stackoverflow.com/questions/15153491/hide-close-x-button-on-excel-vba-userform-for-my-progress-bar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!