Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2016 VBA - Tester si le Menu Système est présent dans un UserForm

Dudu2

XLDnaute Barbatruc
Bonjour,

J'arrive à ajouter le Menu Système à un UserForm par contre je suis incapable de déterminer a postériori si ce Menu Système est présent ou pas.
Je ne sais pas comment traiter le iStyle pour retourner un booléen.
Voir le fichier joint (modifié à 22h30 car initialement bugué)
 

Pièces jointes

  • Test System Menu Present.xlsm
    30.9 KB · Affichages: 3
Dernière édition:
Solution

Dranreb

XLDnaute Barbatruc
Moi VBA7 mais en 32bits.
c'est les api qui on besoin de doubler
Non, ça c'est une légende urbaine du monde des programmeurs qui n'ont jamais pratiqué aucun langage assembleur et qui ne comprennent jamais rien à rien en profondeur.
Le LongPtr assumé LongLong pour Win64 n'est réellement requis que pour contenir des adresses, et ce partout dans du code, pas seulement pour les api.
À la rigueur ça s'étend peut être à deux autres choses :
1) — Les handle renvoyés par Windows pointant sur des zone de mémoire allouées dynamiquement, qui pourraient aussi être en nombre supérieur à ce qui peut tenir sur 32 bits, auquel cas il en faudrait plus pour pouvoir les distinguer.
(mais de toute façon à mon avis pas les handle de fenêtres ni d'applications)
2) — Le 3ième paramètre de l'api MoveMemory qui serait en principe capable de déplacer une portion de mémoire de taille dépassant aussi cette limite.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
on ne c'est pas compris mon bon amis
typename te donnera toujours long avec une valeur numérique sans décimale que ce soit une addresse memoire(longlong,longptr) ou quoi que ce soit d'autre

msgbox typename(application.hwnd) te donnera un long (même en 64 bits)'exemple Handle
msgbox typename(getdc(0)) te donnera un long (même en 64 bits)'exemple contexte hdc

donc ton test n'a tout simplement pas de sens dans le contexte de cette discussion
 

Dranreb

XLDnaute Barbatruc
@patricktoulon, non. Essaie MsgBox TypeName(X), X étant déclarée As LongLong, si ce type de donnée existe dans ton VBA, tu verra bien.
MsgBox TypeName(Application.Hwnd) affiche "Long" parce que c'est un Long, codé sur 32 bits, c'est tout. Autre source de vérification possible: l'explorateur d'objet, bibliothèque Excel, classe Application, membre Hwnd donne chez moi Property Hwnd As Long, lecture seule, Membre de Excel.Application.
Remarque: LongPtr n'est pas un vrai type de donnée. Une variable déclarée As LongPtr sera en réalité de type Long sur 32bits et LongLong sur 64bits.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
oui a partir du moment ou tu variabilise le typename te renverra le type que tu lui a donné
mais là en l’occurrence msgbox typename (application.hwnd) renvoie bien un long en 32 et 64 bits
je précise que j'ai testé sur 2013 32 et 2016 64
 

Dranreb

XLDnaute Barbatruc
Merci de cette confirmation.
Et dans l'explorateur d'objet quel est le statut de la propriété Hwnd de l'objet Application (variabilisé (?) comme dit patricktoulon par la bibliothèque Excel) ?

Conclusion : Un handle d'application tient sur 32 bits. C'est normal: ce n'est jamais qu'un indice dans une table d'adresses détenue et gérée par Windows au gré des allocations dynamiques demandées.
Il y en a toujours largement moins de 2 147 483 647 pour les fenêtres et applications en cours.
 
Dernière édition:

jurassic pork

XLDnaute Occasionnel
Bonjour,

J'arrive à ajouter le Menu Système à un UserForm par contre je suis incapable de déterminer a postériori si ce Menu Système est présent ou pas.
Je ne sais pas comment traiter le iStyle pour retourner un booléen.
Hello,
Avec le module de classe stdWindow, la gestion des fenêtres windows devient facile :
Par exemple voici du code qui affiche l'état des boutons du menu système et qui joue avec. Il y a aussi le masquage de la barre de menu :
VB:
Sub TestMenuSystème()
  Dim usf As stdWindow, st As Single
  Set usf = stdWindow.CreateFromIUnknown(UserForm1)
  usf.Visible = True: usf.x = 500: usf.y = 500
  UserForm1.Label1.Caption = "Croix : " & usf.isSystemMenuVisible _
                   & " - Min : " & usf.isMinimiseButtonVisible _
                   & " - Max : " & usf.isMaximiseButtonVisible _
                   & " - Style : " & usf.Style
  st = Timer: Do While Timer - st < 4.55: DoEvents: Loop
  usf.isSystemMenuVisible = False
  UserForm1.Label1.Caption = "Croix : " & usf.isSystemMenuVisible _
                   & " - Min : " & usf.isMinimiseButtonVisible _
                   & " - Max : " & usf.isMaximiseButtonVisible _
                   & " - Style : " & usf.Style
  st = Timer: Do While Timer - st < 4.55: DoEvents: Loop
  usf.isSystemMenuVisible = True: usf.isMinimiseButtonVisible = True: usf.isMaximiseButtonVisible = True
  UserForm1.Label1.Caption = "Croix : " & usf.isSystemMenuVisible _
                   & " - Min : " & usf.isMinimiseButtonVisible _
                   & " - Max : " & usf.isMaximiseButtonVisible _
                   & " - Style : " & usf.Style
  st = Timer: Do While Timer - st < 4.55: DoEvents: Loop
  usf.isCaptionVisible = False
  UserForm1.Label1.Caption = "Masquage de la barre de menu"
  st = Timer: Do While Timer - st < 4.55: DoEvents: Loop
  usf.isCaptionVisible = "True": usf.isMinimiseButtonVisible = False: usf.isMaximiseButtonVisible = False
  UserForm1.Label1.Caption = "Retour à l'état initial"
End Sub



Pour montrer la puissance de ce module de classe voici du code qui liste les fenêtres windows dans l'état visible et quelques propriétés :
VB:
Sub ListAllVisibleWindows()
    Dim wn As stdWindow
    For Each wn In stdWindow.CreateFromDesktop.children
        If wn.Visible = True Then
           Debug.Print wn.Caption, wn.Class, wn.ProcessID, wn.handle, wn.State
        End If
    Next wn
End Sub

A noter qu'il faut aussi installer le module de classe stdICallable pour que le module de classe stdWindow fonctionne.

Ami calmant, J.P
 

Dudu2

XLDnaute Barbatruc
Bonjour,

@patricktoulon, oui tout ça c'est de la vieille histoire, je sais faire maintenant et dans le code ci-dessous destiné à notre nouvelle ressource pas encore publiée de suppression / rajout ajustés du Caption d'un UserForm, il y a la fonction IsCaptionPresent().

Par contre ces classes sont très intéressantes et ça a l'air très complet. Une compilation de tout ce qu'on peut faire qui peut servir de modèle pour d'autres choses.

Fichier: voir plus loin car correction !
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
ben c'est simple
exemple
je rajoute le bouton agrandir
tu fait
lestyle=getwindowlong (hwnd,-16)'ici lestyle te donne au format hex &H94C80080
'on a donc notre style original
maintenant j'ajoute le bouton agrandir
setwindowlong hwnd,-16,lestyle or &h10000
'maintenant si je refait un getwindowlong
newstyle=getwindowlong (hwnd,-16)'ici le newstyle va me donner &H94C90080
c'est pas compliqué

la liste avec ta methode additionnel
&H10000 = le bouton agrandir
&H20000= le bouton reduire
&H30000= les deux
&H40000= le resize(élasticité)
&H70000= ben c'est les 4
a supposer que tu veux le bouton agrandir et l’élasticité
ben tu ajoute au style normal(&H94C80080) 10000+400000
ca done
setwindowlong hwnd,-16,&H94C80080 or &h10000 or &H40000

ou
setwindowlong hwnd,-16,&H94C80080 or &h50000
et si je fait un test getwindowlong maintenant
newstyle=getwindowlong (hwnd,-16)'ici ca donne &H94CD0080
ben moi je passe direct par
setwindowlong hwnd,-16,&H94CD0080
c'est pas compliqué
 

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…