Bonjour a tous
la demande ayant été faite par un demandeur novice et utilisant une usine a gaz bourrée d'api pour créer un menupopup (menu contextuel ) dans un userform
je me suis penché sur la question comment simplifier le tout
tout d'abords pour concevoir un popup nous n'avons pas vraiment besoins des apis on utilisera les commandbarpopup qui sont la pour ca d'ailleurs
ensuite j'ai décidé de concevoir carrément une toolbar la je me suis dis bonjour l'usine a gaz
mais non mais non!!!
on va faire très simple avec 3 fois rien
on va faire une fonction dans la quelle on injectera un array un peu particulier contenant toutes les données concernant le popup
voila
on commence par mettre des labels en top de userform et tout le long les uns après les autres
ensuite on va mettre dans leur evenement"click" ce genre de code
ici je vais donner 3 exemple
quèsaco me direz vous
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 Private Sub Label1_Click() Dim boutons boutons = Array("Sauver:3:1:macro1", "Sauve sous...:22:1:macro2", "Ouvrir:23:1:macro3", "Importer:128:1:macro4", _ Array("plein ecran:457:1:macro7", "normal:458:1:macro8", "affichage"), _ "Exporter:129:1:macro5", "Quitter:5955:1:macro6") menu boutons, Label1, "usf" End Sub Private Sub Label2_Click() Dim boutons boutons = Array("ajouter du texte:444:1:ajouttext", "mettre le texte en couleur:1916:1:textcolor", "mettre le texte en gras:356:1:textbold", "ombre aux texte:128:7563:ombretexte", _ "copier la selection:236:1:copieselect", "formater:824:1:formater") menu boutons, Label2, "usf" End Sub Private Sub Label3_Click() Dim boutons boutons = Array("inserer une image:524:1:insertimage", _ Array("forme ronde:289:1:macro7", "forme carré:366:1:macro8", "insérer une forme"), "insérer un block texte:356:1:insertextblock") menu boutons, Label3, "usf" End Sub
et bien c'est tout simple
décortiquons le label1
boutons = Array("Sauver:3:1:macro1", "Sauve sous...:22:1:macro2", "Ouvrir:23:1:macro3", "Importer:128:1:macro4", _
Array("plein ecran:457:1:macro7", "normal:458:1:macro8", "affichage"), _
"Exporter:129:1:macro5", "Quitter:5955:1:macro6")
voila visuellement c'est plus facile avec les couleur
chaque couleur représente un bouton de la barre popup
dans chaque element de l'array il y a:
- le nom du bouton (sa caption )
- le face id (le numéro correspondant a l'icon )
- son état (0disabled/1enabled)
- et enfin le nom de la fonction que le bouton est sensé appeler
ces 4 données étant séparées par un ":"
jusque la pas trop compliqué
j'ai mis en gras un élément de l'array qui ne correspond pas a la structure des autres
en effet c'est un array en l'occurrence ici un sub array (un array dans un array)
et bien ce sub array repente vous l'avez compris en regardant sa structure intérieur c'est un submenu
la fonction se charge de placer le sub menu et sa structure
la fonction s'apellera comme suit
menu boutons, Label1, "usf"
remarquez "usf" il est la pour signaler a la fonction que l'on est dans un userform et qu'elle va donc devoir utiliser les apis pour positionner le popup
si vous voulez vous en servir dans un sheets par exemple au clickdroite vous enlevez tout simplement "usf" le popup sortira au point du curseur
voila vous savez comment on appelle la fonction de création du menu
la fonction:
on utilisera pour une commodité visuelle quand même 3/4 api pour un positionnement fixe du popup juste en dessous chaque label
je pense avoir bien fait pour le 32/64 bytes versions excel vous me le direz cas échéant
une chose que vous devez savoir pour un soucis de transportabilité j'ai fait en sorte que tout le code ci dessous puisse être placé dans l'userform ou un module a vous de voir
et voila une démo
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 Option Explicit #If VBA7 Then Private Declare ptrsafe Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long Private Declare ptrsafe Function GetDC Lib "user32" (ByVal hWnd As Long) As Long Private Declare ptrsafe Function GetDeviceCaps Lib "gdi32" (ByVal HdC As Long, ByVal nIndex As Long) As Long Private Declare ptrsafe Function GetActiveWindow Lib "user32" () As Long #Else Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal HdC As Long, ByVal nIndex As Long) As Long Private Declare Function GetActiveWindow Lib "user32" () As Long Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long #End If Private Type RECT: Left As Long: Top As Long: Right As Long: Bottom As Long: End Type Const LOGPIXELSX = 88 Const LOGPIXELSY = 90 Function menu(boutons, bt, Optional mode As String = "") Dim i As Long, Barre As CommandBar, pop, e As Long, decal As Long, r As RECT, XX, YiN As Long, HdC As Long, EpS, lpppX As Long, lpppy As Long, YY As Long On Error GoTo suite delmenu suite: HdC = GetDC(0): lpppX = GetDeviceCaps(HdC, LOGPIXELSX): lpppy = GetDeviceCaps(HdC, LOGPIXELSY) Set Barre = CommandBars.Add("MenuUSF", msoBarPopup, False, True) For i = 0 To UBound(boutons) If IsArray(boutons(i)) Then Set pop = Barre.Controls.Add(msoControlPopup, 1, , , True): pop.Caption = boutons(i)(UBound(boutons(i))) pop.Caption = boutons(i)(UBound(boutons(i))) For e = 0 To UBound(boutons(i)) - 1 With pop.Controls.Add(msoControlButton, 1, , , True) .Caption = Split(boutons(i)(e), ":")(0) .FaceId = Split(boutons(i)(e), ":")(1) .Enabled = Val(Split(boutons(i)(e), ":")(2)) .OnAction = Split(boutons(i)(e), ":")(3) End With Next Else With Barre.Controls.Add(msoControlButton, 1, , , True) .Caption = Split(boutons(i), ":")(0) .FaceId = Split(boutons(i), ":")(1) .Enabled = Val(Split(boutons(i), ":")(2)) .OnAction = Split(boutons(i), ":")(3) End With End If Next DoEvents If mode = "usf" Then GetWindowRect GetActiveWindow, r ' coordonnées rectangle de l'userform XX = bt.Left * lpppX / 72 'position left du label cliqué en pixel YY = (bt.Top + bt.Height) * lpppy / 72 ' position top du label cliqué en pixel YiN = (bt.Parent.Height - bt.Parent.InsideHeight - 3) * lpppy / 72 ' epaisseur de la caption du userform en pixel 'YiN = GetSystemMetrics(15) ' autre methode epaisseur de la caption du userform en pixel mais moins precise EpS = GetSystemMetrics(5) ' epaisseur des bordures de l' userform en pixel Barre.ShowPopup r.Left + EpS + XX, r.Top + YiN + EpS + YY ' affichage de la popup au cordonnéees calculées Else Barre.ShowPopup End If End Function Function delmenu() On Error Resume Next CommandBars("MenuUSF").Delete End Function
des retours sur l'affichage avec des résolutions différentes me seraient utilises pour confirmer le positionnement avec les apis
merci donc d'avance pour ces retours
Partager