Tout commenca pour une simple constation: j'utilise deux moniteur sur mon PC pour agrandir le bureau windows, seulement voila: les Menu contextuel de VB (PopupMenu) de peuvent s'afficher que sur l'ecran 1, donc un click droit sur l'application alors qu'elle est sur l'ecran 2 affiche le menu sur l'ecran 1 :-( , g donc decide de refaire un menu grace au API.
L'utilisation des API pour créer des menus est assez compliqué, de grandes etapes de declaration et de constante à passer au fonction, des parametres compliqués.
G donc créer 2 fichiers: une classe et un module qui fonctionne ensemble:
la classe permet toutes les operations de base (deja plus elaborer que les menus standard de VB), c'est à dire:
creation du menu
ajout d'un texte (normal/gras, actif/desactive, grisé/non grisé, coché/non coché, image de coche ou non, ...)
ajout d'une separation (vertical/horizontal, visible/non visible)
affichage du menu
destruction du menu
le module est ajouté a cause d'un probleme rencontrer: l'utilisation des API est differentes pour afficher une image ou du texte, la fonction utilisé doit avoir le nom de type de donnée mais le type doit être different. Comme il est impossible d'avoir deux type different sous le même nom dans une même classe, g declarer le type en private dans la classe pour le texte et le type pour les images en private dans le module (c pas tres propre de faire ca mais g pas trouvé d'autre solution :-( )
Donc le module lui permet d'afficher les images avec les mêmes parametres que le texte (grisé/non grisé, ....)
Même si la fonction est dans le module tout est lancé de la classe, donc a l'utilisation, on ne voit pas la difference, ce juste qu'il ne faut pas oublier d'importer le module.
Les images affichées (aussi bien les images boutons que les images checked ou unchecked, ...) sont passé sous forme de handle. par exemple, on charge une image dans une PictureBox PictureBox1 par
PictureBox1.Picture = LoadBitmap(...)
et on passe en parametres pour ajouter l'image dans le menu le hendle de l'image chargé:
PictureBox1.Picture.Handle
Source / Exemple :
'Déclaration des API / type / constantes utilisés pour le creation d'un menu avec les API
'TYPE
'type MENUITEMINFO declarer dans la classe
Private Type MENUITEMINFO
cbSize As Long
fMask As Long
fType As Long
fState As Long
wID As Long
hSubMenu As Long
hbmpChecked As Long
hbmpUnchecked As Long
dwItemData As Long
dwTypeData As String
cch As Long
End Type
'type MENUITEMINFO declarer dans le module
Private Type MENUITEMINFO
cbSize As Long
fMask As Long
fType As Long
fState As Long
wID As Long
hSubMenu As Long
hbmpChecked As Long
hbmpUnchecked As Long
dwItemData As Long
dwTypeData As Long 'le type n'est plus une string mais un long
cch As Long
End Type
Private Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type
Private Type TPMPARAMS
cbSize As Long
rcExclude As RECT
End Type
Private Type POINT_TYPE
X As Long
Y As Long
End Type
'CONSTANTE
Private Const MIIM_STATE = &H1
Private Const MIIM_ID = &H2
Private Const MIIM_SUBMENU = &H4
Private Const MIIM_CHECKMARKS = &H8
Private Const MIIM_DATA = &H20
Private Const MIIM_TYPE = &H10
Private Const MFT_BITMAP = &H4
Private Const MFT_MENUBARBREAK = &H20
Private Const MFT_MENUBREAK = &H40
Private Const MFT_OWNERDRAW = &H100
Private Const MFT_RADIOCHECK = &H200
Private Const MFT_RIGHTJUSTIFY = &H4000
Private Const MFT_RIGHTORDER = &H2000
Private Const MFT_SEPARATOR = &H800
Private Const MFT_STRING = &H0
Private Const MFS_CHECKED = &H8
Private Const MFS_DEFAULT = &H1000
Private Const MFS_DISABLED = &H2
Private Const MFS_ENABLED = &H0
Private Const MFS_GRAYED = &H1
Private Const MFS_HILITE = &H80
Private Const MFS_UNCHECKED = &H0
Private Const MFS_UNHILITE = &H0
Private Const TPM_CENTERALIGN = &H4
Private Const TPM_LEFTALIGN = &H0
Private Const TPM_RIGHTALIGN = &H8
Private Const TPM_BOTTOMALIGN = &H20
Private Const TPM_TOPALIGN = &H0
Private Const TPM_VCENTERALIGN = &H10
Private Const TPM_NONOTIFY = &H80
Private Const TPM_RETURNCMD = &H100
Private Const TPM_LEFTBUTTON = &H0
Private Const TPM_RIGHTBUTTON = &H2
Private Const TPM_HORIZONTAL = &H0
Private Const TPM_VERTICAL = &H40
'SUB / FUNCTION
'Creation du menu
Private Declare Function CreatePopupMenu Lib "user32.dll" () As Long
'Destruction du menu
Private Declare Function DestroyMenu Lib "user32.dll" _
(ByVal hMenu As Long) As Long
'Insertion d'un element dans le menu
Private Declare Function InsertMenuItem Lib "user32.dll" Alias "InsertMenuItemA" _
(ByVal hMenu As Long, _
ByVal uItem As Long, _
ByVal fByPosition As Long, _
lpmii As MENUITEMINFO) As Long
'Affichage du menu
Private Declare Function TrackPopupMenuEx Lib "user32.dll" _
(ByVal hMenu As Long, _
ByVal fuFlags As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal hWnd As Long, _
lptpm As TPMPARAMS) As Long
'recuperation de la position de la souris (pour afficher le menu a cette position)
Private Declare Function GetCursorPos Lib "user32.dll" _
(lpPoint As POINT_TYPE) As Long
'creation de la zone d'affichage du menu
Private Declare Function SetRectEmpty Lib "user32.dll" _
(lpRect As RECT) As Long
Conclusion :
Toutes les sources (classe et module) et un exemple simple d'utilsation avec toutes les fonctions dans le ZIP (source VB5 ou superieur)
Voir la capture pour un exemple dans un programme