XL 2016 Gérer un évènement sur un grand nombre de contrôles de même type d'un UserForm

Dudu2

XLDnaute Barbatruc
Bonjour,

J'ai 100 TextBoxes dans un UserForm.
Je voudrais gérer soit le _Enter soit le _DblClick sur tous ces contrôles pour y faire quelque chose de commun.
Pour éviter de déclarer 100 fois dans le code du UserForm le même évènement sur chacune des TextBoxes j'aimerais savoir s'il y a un autre possibilité, genre une classe dédiée.
Mais je ne suis pas très expert dans ce domaine et serais reconnaissant pour toute aide apportée sur la méthode.

Ci-joint un fichier avec 1 userForm de 3 TextBoxes comme base pour proposer un code qui ferait un simple MsgBox "Hello" sur un double-clic dans toutes les TextBoxes.
Merci par avance.
 

Pièces jointes

  • Classeur1.xlsm
    21.7 KB · Affichages: 6

patricktoulon

XLDnaute Barbatruc
ma fois c'est obscure ton truc
perso moi j'ajoute
le userform a la taskList(DANS LA TASKBAR !!)des son demarrage
comme ça quand je minimise ou qu'il est caché par une autre fenêtre , j'y ai toujours accès dans la barre des tache

et oui je dis bien dans la taskbar pas juste au dessus
démonstration quand il est affiché regarde ce que la liste dans la barre des taches me sort
1664004992123.png


demonstration quand il est minimisé
1664005198343.png


voilà pas de galères dans le teston

et là mon ami y a pas de soucis ou questionnement sur sa position minimisé tu sais toujours ou le récupérer et il ne cache rien d'une autre fenêtre
😁
 

patricktoulon

XLDnaute Barbatruc
re
pas de nouvelle????
j'aurais pensé que tu serais plus intéressé par une vrai réduction dans la barre des tache plutôt que du bricolage
qui certes fonctionne mais n'est pas vraiment universelle
si tu es intéressé par la vrai réduction(l'iconage dans la taskbar ) fait moi signe
là je pars pour le reste de la journée je te répondrais ce soir
 

dysorthographie

XLDnaute Accro
Bonjour,
tu trouveras dans le zip un contrôle timer
Code:
Private Sub UserForm_Initialize()
Me.MyTimer1.Interval = 500 '500 mili secondes!
End Sub
Private Sub MyTimer1_Tick()
Static Enciens As String
 If Enciens <> Me.ActiveControl.Name Then MsgBox "Enter Control " & Me.ActiveControl.Name
 Enciens = Me.ActiveControl.Name
End Sub
 

Pièces jointes

  • TimerRD.zip
    34.7 KB · Affichages: 2
Dernière édition:

Dudu2

XLDnaute Barbatruc
Bonjour @dysorthographie,
Tu es sûr que c'est pour ce sujet ?
D'ailleurs même si ça ne l'est pas comment ajouter ce contrôle ?
J'obtiens ça en désignant le contrôle pour Excel (mais c'est peut-être uniquement pour Word ?)
Problème de Sécurité des Options Internet ?
1664034392862.png
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Merci pour l'info @dysorthographie, ça fonctionne.
Je n'aurais jamais eu l'idée d'aller dans les Outils/Références. J'étais plutôt dans l'ajout de contrôles Active X.
Et donc ce Control permet un Timer en UserForm ! C'est cool parce que le Application.Ontime refuse des références à des fonctions internes au UserForm, même publiques.
 

patricktoulon

XLDnaute Barbatruc
re
tiens met ca dans un userform
reduit et regarde dans ta barre de tache

VB:
'*********************************************
'USERFORM REDUIT DANS LA BARRE DES TACHES
'BY patricktoulon

Option Explicit

'API functions
#If VBA7 Then
    #If Win64 Then
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
        Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
        Private Declare PtrSafe Function SetWindowPos Lib "user32" (ByVal hWnd As LongPtr, 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
        Private Declare PtrSafe Function GetActiveWindow Lib "user32.dll" () As LongPtr
        Dim HwnDuSF As LongPtr
    #Else
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
        Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
        Private Declare PtrSafe 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
        Private Declare PtrSafe Function GetActiveWindow Lib "user32.dll" () As Long
        Dim HwnDuSF&
    #End If
#Else
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    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 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
    Private Declare Function GetActiveWindow Lib "user32.dll" () As Long
    Dim HwnDuSF&
#End If

Private Sub UserForm_Activate()
    trois_boutons
    ajout_dans_la_taskList Me
End Sub


'on ajoute les boutons minimiser et maximiser  à l'userform
Private Sub trois_boutons()
    HwnDuSF& = GetActiveWindow
    SetWindowLong HwnDuSF&, -16, &H94C80080 Or &H94CF8080
    SetWindowPos HwnDuSF&, 0, 0, 0, 0, 0, &H20 Or &H2 Or &H1
End Sub

Private Sub ajout_dans_la_taskList(myForm)
    SetWindowPos HwnDuSF&, 0, 0, 0, 0, 0, &H2 Or &H1 Or &H10 Or &H80
    SetWindowLong HwnDuSF&, -20, &H101 Or &H40101
    SetWindowPos HwnDuSF&, 0, 0, 0, 0, 0, &H2 Or &H1 Or &H10 Or &H40
End Sub
voilà ton userform est iconable ;)
 

Dudu2

XLDnaute Barbatruc
@dysorthographie, oui merci j'ai vu.

@patricktoulon, et oui, formidable, ça fonctionne.
Cependant je n'ai pas retrouvé les constantes de:
VB:
SetWindowLong HwnDuSF&, -20, &H101 Or &H40101
dans la doc de l'API. Je ne sais pas à quoi cela correspond.

L'adaptation que j'en ai faite fonctionne aussi (tu me connais j'aime bien les trucs à rallonge ;) )
VB:
'Window field offsets for GetWindowLong() or SetWindowLong()
Private Const GWL_STYLE As Long = (-16)
Private Const GWL_EXSTYLE = (-20)

'Window Styles
Private Const WS_SYSMENU As Long = &H80000
Private Const WS_SIZEBOX As Long = &H40000
Private Const WS_MAXIMIZEBOX As Long = &H10000
Private Const WS_MINIMIZEBOX As Long = &H20000
Private Const WS_THICKFRAME = &H40000
'
'ShowWindow() Commands
Private Const SW_SHOWMAXIMIZED       As Long = 3
Private Const SW_SHOWMINIMIZED       As Long = 2
Private Const SW_RESTORE             As Long = 9

'SetWindowPos Flags
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_FRAMECHANGED = &H20
Private Const SWP_SHOWWINDOW = &H40
Private Const SWP_HIDEWINDOW = &H80

'-----------------------------------
'Place the UserForm in the Task List
'-----------------------------------
Private Sub UserFormInTaksList(Usf As Object)
    SetWindowPos Usf.UsfHandle, 0, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE Or SWP_HIDEWINDOW
    SetWindowLong Usf.UsfHandle, GWL_EXSTYLE, WS_THICKFRAME
    SetWindowPos Usf.UsfHandle, 0, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE Or SWP_SHOWWINDOW
End Sub
 

patricktoulon

XLDnaute Barbatruc
re
ben fonctionner elle ne peut que fonctionner tu a juste variabiliser les constantes
perso je les connais par coeur donc ....
bref tu vois des solutions il y a
et bien plus propres que des bricolages même si ils marchent
sauf si bien sur ça a un intérêt quelconque de positionner le userform réduit a un endroit précis ce dont je doute
puisque tu a l'air de vouloir faire les chosesavec des méthodes orthodoxes je pense que tu optera pour cette solution propre
 

Dudu2

XLDnaute Barbatruc
des solutions il y a et bien plus propres que des bricolages même si ils marchent
En fait je vois la solution TaskBar comme une solution supplémentaire.
Je ne considère pas que les autres ne soient pas "propres" car elles utilisent l'API de façon similaire toute aussi propre et il peut être utile pour l'utilisateur de voir dans sa zone de travail le Header du UserForm cliquable plutôt que de le chercher parmi les tâches de la TaskBar.

Enfin, merci pour cette suggestion et ton code que j'ai implémentés comme une 3ème solution.
Je vais faire de ce classeur une ressource, à toutes fins utiles, faisant référence à ton aide évidemment.
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Bonjour @patricktoulon,
Pour l'instant je vais en rester là. J'ai aussi la suppression du Caption comme bricolage possible mais évidemment incompatible avec le menu système, objet de ce fichier.

D'ailleurs j'ai simplifié car la minimisation relative à l'écran n'a pas vraiment d'intérêt puisque pour un utilisateur sa référence de travail est la fenêtre Excel, maximisée la plupart du temps. Je n'ai donc gardé que la minimisation par rapport à la fenêtre Excel sans la modification du Parent qui change le style du UserForm.

Edit: fichier supprimé, voir plus loin
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Tiens, j'ai une question d'un utilisateur justement...
Est-ce que tu sais rendre l'affichage d'un UserForm permanent, c'est à dire qu'il reste affiché quand on change de fenêtre Excel ?

Ça ?
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 329
Messages
2 087 334
Membres
103 519
dernier inscrit
Thomas_grc11