web-dev-qa-db-fra.com

Masquer le bouton de fermeture [X] sur Excel pour les utilisateurs

J'ai créé un formulaire utilisateur pour afficher une barre de progression lorsque la macro est encore en train d'importer des feuilles enter image description here

Le problème est que l'utilisateur peut appuyer sur le bouton rouge [X] qui ferme et interrompt le traitement.

Existe-t-il un moyen de masquer ce bouton rouge de Doom afin que les utilisateurs potentiels ne puissent cliquer sur aucun bouton prêtant à confusion pendant le fonctionnement? 

modifier:

J'ai essayé ça

'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

et j'ai utilisé cela sur 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)

Je reçois ce message d'erreur enter image description here

ce code a été pris de ici . Je ne sais pas ce que je fais mal et j'ai déjà supprimé les commentaires. C'est le code le plus simple que j'ai trouvé, donc j'aimerais l'intégrer à mon formulaire utilisateur. Toute aide est appréciée.

9
forums

Voici une routine que vous pouvez appeler comme ceci:

subRemoveCloseButton MyForm

ou depuis votre formulaire:

subRemoveCloseButton Me 

Voici le code dont vous aurez besoin:

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
15
Peter Albert

Vous pouvez résoudre le problème à partir des extraits suivants:

Sélectionnez le bouton cmdClose Dans la barre de menus, choisissez View | Code Lorsque le curseur clignote, entrez le code suivant:

Private Sub cmdClose_Click()
  Unload Me
End Sub

Dans la barre de menus, choisissez View | Object pour revenir à l'objet UserForm.

Pour permettre aux utilisateurs de fermer le formulaire en appuyant sur la touche Echap:

Sélectionnez le bouton cmdCloseDans la fenêtre Propriétés, définissez la propriété Cancel sur True.

Pour empêcher les utilisateurs de fermer le formulaire en cliquant sur le bouton X

Lorsque la UserForm est ouverte, il y a une X en haut à droite. En plus d'utiliser le bouton Fermer le formulaire, les utilisateurs pourront fermer le formulaire à l'aide de X. Si vous souhaitez éviter cela, procédez comme suit.

Cliquez avec le bouton droit sur une partie vide de l'objet UserForm Choisissez View | Code Dans le menu déroulant Procédure, dans le coin supérieur droit, choisissez QueryClose.

Où le curseur clignote, collez le code en surbrillance à partir de l'exemple suivant

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

Dans la barre de menus, choisissez View | Object pour revenir à l'objet UserForm . Si un utilisateur clique sur la variable X dans l'objet UserForm, il verra votre message.

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

8
JustinJDavies

J'ai trouvé la contribution de Justin Davies plutôt utile: si vous remplacez la ligne

MsgBox "Please use the Close Form button!"

avec

UserformX.hide

le Userform est caché à l'utilisateur mais reste actif jusqu'à son déchargement.

3
Peter Balzer

Ceci est une amélioration de la réponse ci-dessus de Peter Albert.

  • Les appels API Windows sont désormais sécurisés pour Office x64
  • FindWindow call a été amélioré pour rechercher uniquement les fichiers Excel Excel. La fonction dans la réponse d'origine recherche dans chaque classe de fenêtre (par exemple, les fenêtres Explorer et les fenêtres d'un autre programme). Par conséquent, il peut arriver que le bouton [x] d’autres programmes ou fenêtres d’explorateur soit supprimé lorsque leur nom est identique à 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?
Les UserForms dans Excel appartiennent en réalité à la classe Windows ThunderDFrame, qui est la classe de tous les UserFroms dans les applications Microsoft Office après 2002. Avant cela, il s'agissait de ThunderXFrame.

3
Pᴇʜ

Je sais que c’est une vieille question, mais pour le type d’utilisateur du OP cité, il n’est pas nécessaire de supprimer, masquer ou désactiver le bouton de fermeture. Il y a un moyen beaucoup plus simple;)

Pour tout formulaire utilisateur qui ne contient aucun élément avec lequel l'utilisateur interagit (boutons, etc.) et qui se fermera lui-même lorsqu'il aura terminé sa tâche, il suffit de le désactiver.

Pour désactiver le formulaire utilisateur: Dans les propriétés du formulaire, définissez False sur Activé. Le formulaire utilisateur montrera jusqu'à ce que son code lui indique de se cacher. L'utilisateur ne pourra rien faire avec le formulaire (ne peut pas fermer, ne peut pas se déplacer, etc.).

Notez également que si vous souhaitez que l'utilisateur puisse faire autre chose dans la fenêtre principale alors que le formulaire utilisateur est toujours affiché, décide si vous définissez ShowModal.

2
brit0n

Demandez à l'utilisateur s'il souhaite fermer le formulaire - et perdre les modifications (par exemple) . D'après les idées de 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: En fait, j’ai conscience que c’est un sujet hors du sujet, car OP souhaitait supprimer l’option X - mais j’ai néanmoins trouvé cela pratique pour les formulaires interactifs.

2
Richard Briggs

Pour désactiver le bouton, procédez comme suit:

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

Bien que cela ne soit pas débarrassé du bouton, cela ne permet cependant pas de cliquer dessus.

2
Gravity Grave

Vérifiez le lien suivant. Cela a fonctionné pour moi. Il supprime la TitleBar de l'objet UserForm.

https://social.msdn.Microsoft.com/Forums/office/en-US/17452849-598c-410b-8675-b1e585d0e7e7/userform-without-titlebar-and-borders?forum=exceldev

1
Rahul Varadkar