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

Dudu2

XLDnaute Barbatruc
Bonjour,
Quelqu'un a-t-il déjà tenté ce challenge ?
Merci
 

Dudu2

XLDnaute Barbatruc
Ça semble très très difficile, en tous cas je renonce.
Mais c'est pas grave parce que j'ai trouvé un moyen de détecter les Moniteurs sans passer par un EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ByVal 0&
 

Dranreb

XLDnaute Barbatruc
Bonsoir.
Je ne sais pas si ça rejoint votre problème, mais c'est sûr qu'il y a certaines fonctionnalités qui ne peuvent pas être implantées dans des modules objets, en particulier s'il faut utiliser AdressOf, mais pas que: On ne peut non plus préciser une méthode à Application.OnTime par exemple.
Ce que je fais pour l'y utiliser quand même c'est un module standard à usage exclusif d'un module de classe, à usage, lui, d'un module objet utilisateur, pour lequel il décrète un évènement. J'ai comme ça un objet Rythmeur qui décrète périodiquement un évènement Intervient, en se servant de fonctionnalités de bas niveau d'un module standard XRythmeur qui ne sert qu'à ces objets Rythmeur.
 

Dudu2

XLDnaute Barbatruc
Bonjour @Dranreb,
Ne suffit-il pas de placer la fonction de l'AddressOf dans un module standard ?
En l'occurrence, je ne veux utiliser qu'un UserForm pour la fonctionnalité que je développe, donc c'est exclu.
Mais envoie-moi quand même un exemple de ton procédé pour que je puisse l'analyser.
Merci.
 

Dudu2

XLDnaute Barbatruc
Bonjour @patricktoulon,
Je n'utilise QUE MonitorFromPoint et GetMonitorInfo en décalant le Point initial (qui part de 0,0) de la largeur du dernier moniteur trouvé.
Si une info (j'ai pris le rcMonitor.Left) est la même que le moniteur précédent, j'ai fini le parcours des moniteurs.

Testé sur mon Laptop avec l'écran de mon Desktop en secondaire. Je pence que ça doit marcher en toute configuration.
La seule inconnue pour moi est de savoir si le point initial peut être négatif ou pas sur le moniteur primaire ou un secondaire.

Fichier supprimé: voir plus loin.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
chez moi en 32 bit
VB:
Option Explicit


Private Const MONITORINFOF_PRIMARY = &H1
Private Const MONITOR_DEFAULTTONEAREST = &H2
Private Const MONITOR_DEFAULTTONULL = &H0
Private Const MONITOR_DEFAULTTOPRIMARY = &H1

Private Type RECT
  Left As Long
  Top As Long
  Right As Long
  Bottom As Long
End Type

Private Type MONITORINFO
  cbSize As Long
  rcMonitor As RECT
  rcWork As RECT
  dwFlags As Long
End Type

Private Type POINT
  x As Long
  y As Long
End Type

Private Declare Function GetMonitorInfo Lib "user32.dll" Alias "GetMonitorInfoA" (ByVal hMonitor As Long, ByRef lpmi As MONITORINFO) As Long
Private Declare Function MonitorFromPoint Lib "user32.dll" (ByVal x As Long, ByVal y As Long, ByVal dwFlags As Long) As Long
Private Declare Function MonitorFromRect Lib "user32.dll" (ByRef lprc As RECT, ByVal dwFlags As Long) As Long
Private Declare Function MonitorFromWindow Lib "user32.dll" (ByVal hWnd As Long, ByVal dwFlags As Long) As Long
Private Declare Function EnumDisplayMonitors Lib "user32.dll" (ByVal hdc As Long, ByRef lprcClip As Any, ByVal lpfnEnum As Long, ByVal dwData As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Dim hWnd As Long

Private Function MonitorEnumProc(ByVal hMonitor As Long, ByVal hdcMonitor As Long, _
    lprcMonitor As RECT, ByVal dwData As Long) As Long
  Dim MI As MONITORINFO, R As RECT
  Debug.Print "Moitor handle: " + CStr(hMonitor)

  'initialize the MONITORINFO structure
  MI.cbSize = Len(MI)
  'Get the monitor information of the specified monitor
  GetMonitorInfo hMonitor, MI

  'write some information
  Debug.Print "Monitor" & _
    " Left " & MI.rcMonitor.Left & _
    " Top  " & MI.rcMonitor.Top & _
    " Size " & MI.rcMonitor.Right - MI.rcMonitor.Left & "x" & MI.rcMonitor.Bottom - MI _
    .rcMonitor.Top
  Debug.Print "Primary monitor: " + CStr(CBool(MI.dwFlags = MONITORINFOF_PRIMARY))

  'test
  If MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST) = hMonitor Then
    Debug.Print "hWnd is located on this monitor"
  End If

  'heck whether the point (0, 0) lies within the bounds of this monitor
  If MonitorFromPoint(0, 0, MONITOR_DEFAULTTONEAREST) = hMonitor Then
    Debug.Print "The point (0, 0) lies wihthin the range of this monitor..."
  End If

  'check whether Form1 is located on this monitor
  GetWindowRect hWnd, R
  If MonitorFromRect(R, MONITOR_DEFAULTTONEAREST) = hMonitor Then
    Debug.Print "The rectangle of hWnd lies within this monitor"
  End If
  Debug.Print ""

  'Continue enumeration
  MonitorEnumProc = 1
End Function

Sub Main()
  hWnd = FindWindow("XLMAIN", Application.Caption)
  'start the enumeration
  EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ByVal 0&
End Sub
mais le problème reste entier
les résultats vont dépendre du mode d'affichage et la disposition de tes écrans
  1. mode ecran 1/ecran2
  2. étendu(extension du bureau)
  3. ecran1 à gauche ou à droite
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Ne suffit-il pas de placer la fonction de l'AddressOf dans un module standard ?
Oui, de toute façon, il n'y a pas d'autre possibilité. Elle peut appeler directement une méthode écrite dans l'UserForm ou invoquer une méthode qui y décrètera un évènement.
Les exemples pour l'objet Rythmeur utilisant la programmation de base du XRythmeur et pour l'objet Planification utilisant celles du XPlanificateur sont dans ce classeur.
 

Pièces jointes

  • Progression.xlsm
    289 KB · Affichages: 2

Dudu2

XLDnaute Barbatruc
les résultats vont dépendre du mode d'affichage et la disposition de tes écrans
Tu as raison, ça dépend:
  1. mode ecran 1/ecran2
  2. étendu(extension du bureau)
  3. ecran1 à gauche ou à droite
Alors...
  1. Pas de problème, c'est comme si il y avait 1 seul moniteur
  2. Je ne trouve pas de paramètre pour faire ça, je ne sais pas trop ce que ça veut dire
  3. Il faut donc aussi rechercher les moniteurs "avant" le moniteur 1
Pour le point 3, certes je ne connais pas le "vrai" numéro de moniteur au-delà de 2 moniteurs, mais au moins je connais tous les moniteurs et leurs caractéristiques.

Donc pour moi le problème reste quasi-vide.

Edit: De toutes façons, je n'ai pas le choix car je dois détecter les moniteurs dans un UserForm et je ne veux pas de Module. Donc exit le EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ByVal 0&
 

Pièces jointes

  • Moniteurs Monitors.xlsm
    24.3 KB · Affichages: 2
Dernière édition:

patricktoulon

XLDnaute Barbatruc
je ne trouve pas de paramètre pour faire ça, je ne sais pas trop ce que ça veut dire
re
dans les paramètres affichage/écran
normalement si tu a deux écrans tu doit voir la représentation de tes deux écrans dans une fenêtre
et en dessous tu dois avoir un combo pour le choix du type d'affichage
des truc du genre
utiliser comme moniteur principal
étendre l'affichage
c'était comme ça sur windows 7 maintenant sur windows10 ou 11 je ne sais pas
comme j'ai un écran 130 cm, j'ai de quoi afficher 2 fenêtres pas besoins d'2d écran
 

Dudu2

XLDnaute Barbatruc
Sur Windows 10 j'ai ça.
1698840981441.png

Il n'y a rien concernant ce choix en Paramètres d'affichage avancés.
Par défaut je suis en "Étendre ces affichages" qui doit correspondre au Bureau étendu je pense.
 

Dudu2

XLDnaute Barbatruc
Bonsoir,
D'ailleurs, pour ce qui m'intéresse, c.a.d le moniteur qui contient la fenêtre Excel, il y a beaucoup plus simple que le fichier du Post #9. Il faut utiliser la fonction API MonitorFromWindow().
 

Pièces jointes

  • Excel Window Monitor Info.xlsm
    25.6 KB · Affichages: 4

patricktoulon

XLDnaute Barbatruc
re
oui exact post #7

mais c'est pas le soucis en fait aucune api donne le 1 ou le 2
sauf si bien sur on considère que le 1 est le principal et l'autre le secondaire
imagine tu veux afficher excel sur le 1 ou le 2
sachant que le 2 est peut être a gauche du 1 et vise et versa
sachant aussi que l'ecran principal (déterminé dans les paramètres peut être le 2

bref capter les Propriétés autre que les addresses mémoire (handle)et dimensions
n'a aucun intérêt en VBA
 

Discussions similaires

Réponses
29
Affichages
2 K

Statistiques des forums

Discussions
314 628
Messages
2 111 337
Membres
111 105
dernier inscrit
Joffrette