Menu popup utilisant les api (avec images !)

Soyez le premier à donner votre avis sur cette source.

Vue 11 597 fois - Téléchargée 1 768 fois

Description

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

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
336
Date d'inscription
jeudi 30 janvier 2003
Statut
Membre
Dernière intervention
22 février 2019
1
salut,
concernant autocad (qui est un autre sujet), j'avais posté ça:
http://www.vbfrance.com/codes/LIAISON-VB6-AUTOCAD-GRACE-ACAD-TLB_24683.aspx

pour communiquer avec autocad depuis vb6.

si tu veux des exemples vba autocad, j'essayerai de faire qque chose du même style.
Messages postés
336
Date d'inscription
jeudi 30 janvier 2003
Statut
Membre
Dernière intervention
22 février 2019
1
salut,
concernant autocad (qui est un autre sujet), j'avais posté ça:
http://www.vbfrance.com/codes/LIAISON-VB6-AUTOCAD-GRACE-ACAD-TLB_24683.aspx

pour communiquer avec autocad depuis vb6.

si tu veux des exemples vba autocad, j'essayerai de faire qque chose du même style.
Messages postés
181
Date d'inscription
jeudi 30 mai 2002
Statut
Membre
Dernière intervention
19 août 2012

LD40 : J'avoue qu'à l'époque, quand j'ai voulu tester le VBA sous AutoCad, j'ai trouvé ce VBA plutôt limité; je n'ai même pas réussi à programmer le tracé d'une ligne. Peut-être n'ai-je pas assez cherché.
En tout cas, si ce VBA doit contenir toutes les fonctions d'AutoCad, alors AutoDesk a du pain sur la planche! A cette époque, je me disais qu'il vallait mieux programmer en LISP... que je ne connais pas :-(
Cela dit, si tu as des exemples à partager, je suis preneur, histoire de voir comment ça fonctionne.

Pour ce qui est de ta question, j'avoue que j'ai très vite abondonné la source de Tronic car trop contraignante, y compris (et suivant mes souvenirs) l'ordre des items d'un menu et... les fameux séparateurs dont tu parles.

@+ j'espère et bon prog !
Messages postés
336
Date d'inscription
jeudi 30 janvier 2003
Statut
Membre
Dernière intervention
22 février 2019
1
salut,

je reconnais que cet exemple est nickel pour tous les programmeurs vba.
je viens de l'adapter pour mon formulaire vba dans autocad, c'est super!

Petite question:
je n'arrive pas à dessiner un séparateur dans les sous menus ... si tu connais l'astuce ...
Messages postés
2
Date d'inscription
mardi 10 septembre 2002
Statut
Membre
Dernière intervention
29 septembre 2005

Re c'est moi (qui est poster ce code il y a 3ans ...)

Pour repondre a PierrotVB qui me dit que j'ai piquer le code:
je repondrais qu'effectivement j'avais trouvé la déclaration des API dessus, d'ou eventuellement les noms identiquement, seulement l'utilisation etait tres lourde et complexe, donc j'ai refait entièrement tout le code (d'ou le francais qui n'est pas une traduction mais ma propre version). Cela dit je ne sais plus ou j'ai eut la declaration des API la premiere fois, c'est pour ca que je n'est pas citer la source dont je ne me souvenait plus. (J'ai aussi horreur des gens qui s'approprie, je ne le ferai pas ! La j'ai tout refait, a par les API rien n'est d'origine)

Pour repondre a liquide:
ba mon code tu en fait ce que tu veux, si tu veux faire un ActiveX je t'en pris ;) par contre je le ferai pas, je ne me sert plus de mon code, et j'ai plus trop le temps, désolé :(

Pour repondre a TheLordFreddy:
Pour le bug je connais pas, j'ai jamais tester sous XP :( comme dit plus haut je ne m'en sert plus de mon code, je programme en C# maintenant. Et pour ton idée d'amelioration, je doit admettre que ca serait pas mal en effet, mais comme j'ai deja dit, j'ai franchement plus le temps maintenant :(

Bon ba je repasse dans 2ans voir si il y a encore des gens qui utilise ce code lol ;)
Afficher les 24 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.