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

XL 2016 VBA - Alternative à AddressOf dans un module de classe / UserForm

Dudu2

XLDnaute Barbatruc
En fait j'ai eu besoin de ça pour ma dernière ressource d'un "Custom MsgBox".
Pour se comporter par défaut comme le MsgBox (ce qui était pour moi un peu le but du jeu), il faut centrer la fenêtre du UserForm dans l'écran.
Tout ça pour ça !

Par contre pour MAC je ne sais pas trouver le moniteur.
Et je n'ai toujours pas compris ce que renvoient Application.UsableWidth et Application.UsableHeight en MAC. Si ça dépend de la fenêtre ou pas.
 

patricktoulon

XLDnaute Barbatruc
pour mac
avec application .width et application .height quand excel est maximisé te renvoie les dim en pixels
testé par notre ami ryu qui a confirmé mes soupçons

maintenant me Revient une idée simple comme bonjour
je veux afficher une fenêtre dans un des écrans
monitor et rcmonitor
puisque l'on a les handles
pourquoi ne pas se servir de SetParent
c'est tout con comme truc non ?

et là je t'oriente vers la solution que mes camarades et moi avons adopté sur DVP à l'époque
qui nous a permis de nous débarrasser des usines a gaz api pour le multi écrans

il faut raisonner (gauche et droite) et peu importe que ce soit (1/2 ou 2/1)

toi qui a deux écrans que donne
Eg=MonitorFromPoint(-10000, 1, &H2)
Ed= MonitorFromPoint(10000, 1, &H2)
 

Dudu2

XLDnaute Barbatruc
Bonjour,
avec application .width et application .height quand excel est maximisé te renvoie les dim en pixels
testé par notre ami ryu qui a confirmé mes soupçons
Les retours de @RyuAutodidacte ne sont pas très clairs dans la conversation privée qu'on a eu sur le sujet concernant Application.UsableWidth et Application.UsableHeight.

Je ne sais pas si ça veut dire:
  1. L'espace utilisable pour l'application ou
  2. L'espace utilisable dans l'application.
Je pense que c'est la 2ème solution, hélas.

VB:
Sub a()
    MsgBox ActiveWindow.Width & " x " & ActiveWindow.Height & vbCrLf & _
           Application.Width & " x " & Application.Height & vbCrLf & _
           Application.UsableWidth & " x " & Application.UsableHeight & vbCrLf & _
           ActiveWindow.UsableWidth & " x " & ActiveWindow.UsableHeight
End Sub

'https://learn.microsoft.com/fr-fr/office/vba/api/excel.application.usablewidth
'This example expands the active window to the maximum size available (assuming that the window isn't already maximized).
'=> NE FONCTIONNE PAS ! 
Sub b()
    With ActiveWindow
        .WindowState = xlNormal
        .Top = 1
        .Left = 1
        .Height = Application.UsableHeight
        .Width = Application.UsableWidth
    End With
End Sub

Edit: https://learn.microsoft.com/fr-fr/office/vba/api/excel.application.usablewidth

Propriété Application.UsableWidth​

Cette propriété renvoie la largeur maximale, exprimée en points de l'espace pouvant être occupé par une fenêtre dans l'espace de travail de l'application. Double (en lecture seule).
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
toi qui a deux écrans que donne
Eg=MonitorFromPoint(-10000, 1, &H2)
Ed= MonitorFromPoint(10000, 1, &H2)
Là tu fixes des points arbitrairement mais ils peuvent ne pas correspondre à la réalité car par exemple, on peut avoir plusieurs moniteurs en position négative ou positive.

C'est pour ça que dans le fichier du Post #9, le fonction GetMonitorMIs() parcours en positif puis en négatif toutes les possibilités et trouve tous les moniteurs qu'ils soient en négatif ou en positif.
Code:
Function GetMonitorMIs() As MONITORINFO()
    Dim TabMIs() As MONITORINFO
    Dim NbMIs As Integer
   
    Dim hMonitor As LongPtr
    Dim MI As MONITORINFO
    Dim Point As POINTAPI
    Dim PreviousLeft As Long
   
    'Look for monitors on the right of the primary monitor
    Point.X = 0
    Point.Y = 0
    PreviousLeft = -1
   
    Do While 1
        hMonitor = MonitorFromPoint(Point, 2)
        MI.cbSize = Len(MI)
        Call GetMonitorInfo(hMonitor, MI)
        If MI.rcMonitor.Left = PreviousLeft Then Exit Do
        NbMIs = NbMIs + 1
        ReDim Preserve TabMIs(1 To NbMIs)
        TabMIs(NbMIs) = MI
        PreviousLeft = MI.rcMonitor.Left
        Point.X = Point.X + MI.rcMonitor.Right
    Loop
   
    'Look for monitors on the left of the primary monitor
    Point.X = 0
    Point.Y = 0
    PreviousLeft = 1
   
    Do While 1
        hMonitor = MonitorFromPoint(Point, 2)
        MI.cbSize = Len(MI)
        Call GetMonitorInfo(hMonitor, MI)
        If MI.rcMonitor.Left = PreviousLeft Then Exit Do
        If Not Point.X = 0 Then
            NbMIs = NbMIs + 1
            ReDim Preserve TabMIs(1 To NbMIs)
            TabMIs(NbMIs) = MI
        End If
        PreviousLeft = MI.rcMonitor.Left
        Point.X = Point.X + MI.rcMonitor.Left - 1
    Loop
   
    'Return value
    GetMonitorMIs = TabMIs
End Function
 

Dudu2

XLDnaute Barbatruc
Pourquoi tu n'utilises pas la propriété du Userform ?
Très bonne idée.

Par contre, pour mon "Custom MsgBox" j'ai quand même besoin de savoir la taille du moniteur sur lequel se trouve Excel lorsque je dois réduire / ajuster la hauteur du UserForm sur cette taille lorsque ce dernier est trop grand (auquel cas je gère l'affichage du texte avec une Scroll Bar verticale).

Si la fenêtre Excel est maximisée, alors je peux trouver la hauteur utilisable.
Encore que dans ce cas sous Windows ActiveWindow.Top = -4.4 et ActiveWindow.Height > hauteur réelle de la fenêtre !!! Je n'ai jamais compris pourquoi ces dérives.
>>> D'ailleurs en fenêtre maximisée sur MAC j'aimerais bien connaitre ces valeurs.

Si la fenêtre n'est pas maximisée, alors je ne peux pas trouver la hauteur utilisable.
Sauf à la maximiser temporairement mais cela provoquera une "saute d'affichage" certes très rapide pas très agréable.
 

RyuAutodidacte

XLDnaute Impliqué

PS : Fenêtre Excel en Arrière plan à gauche
1ère capture : Comme tu peux le voir si je place tout en bas la fenêtre Excel on voit que le Top est en bas
2ème capture : j'ai remonté la fenêtre Excel et le Top est passé à 494 donc ca confirme la capture 1

Je ne sais pas si c'est la même chose sur PC ?
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
@RyuAutodidacte,
Pour en finir avec ces valeurs, peux-tu STP exécuter ce code en fenêtre maximisée et réduite ?
VB:
Sub a()
    Dim S As String
 
    S = "WindowState = "
 
    Select Case Application.WindowState
        Case xlMaximized
            S = S & "xlMaximized"
        Case xlMinimized
            S = S & "xlMinimized"
        Case xlNormal
            S = S & "xlNormal"
        Case Else
            S = S & "Inconnu"
    End Select
 
    S = S & vbCrLf & vbCrLf & _
        "ActiveWindow:" & vbCrLf
    With ActiveWindow
        S = S & _
            "Left: " & .Left & ", Top: " & .Top & ", Width: " & .Width & ", Height: " & .Height & vbCrLf & _
            "UsableWidth: " & .UsableWidth & ", UsableHeight: " & .UsableHeight
    End With
 
    S = S & vbCrLf & vbCrLf & _
        "Application:" & vbCrLf
    With Application
        S = S & _
            "Left: " & .Left & ", Top: " & .Top & ", Width: " & .Width & ", Height: " & .Height & vbCrLf & _
            "UsableWidth: " & .UsableWidth & ", UsableHeight: " & .UsableHeight
    End With
    
    MsgBox S
End Sub

Chez moi, en écran 1920 x 1080 pixels avec barre des tâches 50 pixels et PtToPx = 1.66666:
 

Pièces jointes

  • 1699017088602.png
    12 KB · Affichages: 2
Dernière édition:

Dudu2

XLDnaute Barbatruc
Évidemment je me suis trompé sur le libellé du .UsableHeight. C'est corrigé.
Alors sous Windows, en xlMaximized il n'y a qu'une seule info exploitable:
Application.UsableWidth = 1152 pt soit 1920 px avec la barre des tâches en bas.
 

patricktoulon

XLDnaute Barbatruc
re
utiliser le startupposition du userform n'est pas bonne non plus
puisque il s'affichera sur l’écran dit(principal)
pour l'afficher sur un écran au choix il va falloir l'apparenter ou jouer avec le Left et top

pour l'apparenter ça ne peut se passer qu'en AddressOf malheureusement dans un module standard
sinon dans le activate jouer avec le left après calcul monitor
 

Dudu2

XLDnaute Barbatruc
utiliser le startupposition du userform n'est pas bonne non plus
puisque il s'affichera sur l’écran dit(principal)
Je ne m'en doutais pas mais c'est exact. StartupPosition = 2 adresse l'écran principal !!!
Donc pour Windows je suis revenu à StartupPosition = 0 en utilisant les coordonnées du moniteur.
Et pour MAC je suis revenu à StartupPosition = 1.
 

Discussions similaires

Réponses
29
Affichages
2 K
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…