Microsoft 365 Forcer l'affichage de mon userform (barre de progression) sur l'écran où le classeur est actif (cas des doubles/triples écrans)

Le_Phénomène

XLDnaute Nouveau
Bonjour,

Dans l'un de mes projets, je fais afficher une barre de progression via un userform afin de faire "patienter" l'utilisateur (et histoire que ce dernier ne panique pas trop lors de traitements un peu longuais ;) - ça les rassure) :
1730798875040.png


Sauf que... selon les configurations des uns et des autres, de leur choix d'ouvrir/placer le classeur Excel sur tel ou tel écran (l'équipe dispose tous d'un double écran avec affichage étendu et certain utilise même leur laptop comme troisième écran), mon userform s'affiche toujours par défaut sur l'écran principal définit dans les paramètres Windows.

Donc pas de souci lorsque l'utilisateur à son classeur ouvert sur le moniteur déclaré comme écran principal mais c'est bof lorsqu'il a décidé de placer son classeur sur l'un des écrans secondaire.

Je souhaiterai donc pouvoir :
1- savoir sur quel écran est activé le classeur Excel qui mouline
2- forcer l'affichage de mon userform sur ledit écran

Si un éminant expert à une solution ou une voie sur laquelle je peux m'orienter, je l'en remercie par avance.

En vous souhaitant une bien agréable journée.
Franck
 
Solution
Bonjour,
Merci @TooFatBoy pour ton (si on peut tutoyer sur ce forum ? 🤔) message.
En fouillant un peu plus, je suis tombé sur un message de @Lolote83 qui semble répondre à ma problématique.
Je ne l'ai pas encore complétement testé sur d'autres postes et sur les triple-écrans.
Il faut également que j'en comprenne bien le sens et l'application (histoire de progresser).
Je ne manquerai pas de clôturer cette demande asap.
Pour mémoire, ci-après son code.

VB:
Private Sub UserForm_Initialize()
    '-------------------------------------------------------- Positionnement UserForm
    Me.StartUpPosition = 0                                                  'Déclarer position MANUAL
    Me.Left = Application.Left +...

Le_Phénomène

XLDnaute Nouveau
Bonjour,
Merci @TooFatBoy pour ton (si on peut tutoyer sur ce forum ? 🤔) message.
En fouillant un peu plus, je suis tombé sur un message de @Lolote83 qui semble répondre à ma problématique.
Je ne l'ai pas encore complétement testé sur d'autres postes et sur les triple-écrans.
Il faut également que j'en comprenne bien le sens et l'application (histoire de progresser).
Je ne manquerai pas de clôturer cette demande asap.
Pour mémoire, ci-après son code.

VB:
Private Sub UserForm_Initialize()
    '-------------------------------------------------------- Positionnement UserForm
    Me.StartUpPosition = 0                                                  'Déclarer position MANUAL
    Me.Left = Application.Left + Application.Width / 2 - Me.Width / 2
    Me.Top = Application.Top + Application.Height / 2 - Me.Height / 2
End Sub
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
Bonjour La meilleure façon de faire pour être sur de l'affichage de ton userform progressbarsur l'application est tres simple
il te suffit de l'apparenter à l'application avec l'api setparent (child,parent)
c'est imparable après tu le place ou tu veux sachant que le point 0 c'est celui de l'application et plus l’écran
voili voilou
car utiliser le left et top de l'app sur multi écran et pour peu que l'app excel ne soit pas sur l'ecran 1 ben c'est pas triste
en affiliant l'userform à l'app Excel tu n'a plus ce problème

oserais-dire aussi que ta barre de progression peut être faite(d'une certaine manière ) dans la barre de statut d'excel ce qui te libère définitivement de ce tracas
à méditer
Patrick
 

Dudu2

XLDnaute Barbatruc
Salut la compagnie,
Alors désolé, j'ai manqué ce sujet et si ce n'est pas trop tard je peux recommander cette ressource:

Et en particulier les fonctions:
- CountOfMonitors (pour savoir combien de moniteurs pour le PC)
- GetActiveWindowMonitorNumber (pour savoir sur quel moniteur se trouve l'Active Window)
- PlaceUserFormInReferenceArea (pour placer le UserForm dans un moniteur dans un zone donnée)
et encore si besoin:
- GetMonitorRECT (pour connaitre le RECT en pixels d'un moniteur)
- PixelsToPointsX et PixelsToPointsY pour transformer les pixels en points pour le positionnement du UserForm)
 

Dudu2

XLDnaute Barbatruc

Pièces jointes

  • VBA Barre de progression en StatusBar.xlsm
    18 KB · Affichages: 7
Dernière édition:

Dudu2

XLDnaute Barbatruc
Alors en effet, c'est une solution beaucoup plus direct puisque @Le_Phénomène veut afficher son UserForm dans la fenêtre active sans distinction de moniteur. ll suffit comme tu l'as fait de définir le Parent du UserForm à l'Application ou l'ActiveWindow.

Il y a quand même un petit effet de bord du SetParent (sur 2016 au moins)
Le UserForm a un style différent:
1730982299501.png


du style classique.
1730982266155.png
 

patricktoulon

XLDnaute Barbatruc
re
oui il est redessiné selon le shell32.dll d'origine qui n'a pas changé depuis W7
rappelle toi depuis c'est dwnmapi.dll qui fait le thème ;)
pour l'avoir au centre et en plus si le style ne plait pas ben on l'enleve la barre de titre
code userform
VB:
'patricktoulon
#If Win64 Then ' (Office 64bit ET Win 64Bit)
    Private Declare PtrSafe Function SetWindowLongA Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongLong, ByVal nIndex As Long, ByVal dwNewLong As LongLong) As LongLong
    Private Declare PtrSafe Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongLong
    Private Declare PtrSafe Function SetParent Lib "user32" (ByVal hWndChild As LongPtr, ByVal hWndNewParent As LongPtr) As LongPtr
#Else ' (Office 32bit ET Win 32Bit) OU (Office 32Bit ET Win 64Bit)
    Private Declare Function SetWindowLongA Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
#End If

Private Sub UserForm_Activate()
    Dim hwnd As LongPtr, pluscentre
    hwnd = FindWindowA(vbNullString, Me.Caption)
    SetWindowLongA hwnd, -16, &H94080080:    Me.Height = Me.Height - 21 'on enlève la barre de titre
    SetParent hwnd, Application.hwnd
    Me.Top = (Application.Height - Me.Height) / 2
    Me.Left = (Application.Width - Me.Width) / 2
End Sub
demo1.gif
 

Statistiques des forums

Discussions
314 588
Messages
2 110 988
Membres
111 002
dernier inscrit
Lolo73i