Search code examples
exceluserformvba

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


I created a userform to show a progress bar when the macro is still importing sheets enter image description here

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 enter image description here

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.


Solution

  • 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