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
Salut les afficheurs de UserForms,

J'ai amélioré ma petite ressource de Barre de Progression Interruptible (sur option):
pour y ajouter:
- le centrage par défaut dans la fenêtre active
- la possibilité de la positionner Left et Top
- la possibilité de la dimensionner en Width et Height
- la possibilité de désigner la couleur de la barre
- la possibilité de supprimer le Caption (barre de menu système de la fenêtre)

Tous les paramètres sont modifiables en cours d'exécution (à chaque appel) de la barre.

En principe ça devrait convenir à @Le_Phénomène sans avoir à trop bricoler.

Je vous mets le fichier de la...

TooFatBoy

XLDnaute Barbatruc
Mon code a une certaine propension à ne pas fonctionner chez @patricktoulon.
1731163656996.gif
C'est ta toute dernière version que j'ai testée. C'est peut-être ça la différence.
Ou alors ça vient encore de son driver vidéo à moitié moisi... 😅

Tant que ta ressources fonctionne chez moi avec un écran normal, un driver vidéo normal, un Excel 2016 32 bits et un Windows 10 64 bits, moi, ça me va. 👍
 

Dudu2

XLDnaute Barbatruc
C'est ta toute dernière version que j'ai testée. C'est peut-être ça la différence.
Je ne crois pas, car @patricktoulon est en VBA7 (Office 2013), donc les derniers ajustements pour les déclarations non-VBA7 ne s'appliquent pas à lui.
Par contre il est 32 bits. Alors le seul endroit où il pourrait y avoir un problème est cette déclaration prise dans ma bible des déclarations API.
VB:
    #If Win64 Then
        Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
        Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
    #Else
        Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
        Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
    #End If
où le 32 bits apparaît dans le #Else.
Mais franchement, je ne vois rien qui justifierait un problème à ce niveau.
J'attends donc un retour d'erreur d'où qu'il vienne pour investiguer.
 

patricktoulon

XLDnaute Barbatruc
@Dudu2 ben tu avais vu les vidéo non?
c'est pas pour t'ennuyer
après c'est pas grave j'ai quelque chose de plus générique sauf que maintenant je n'en ai plus l'utilité
en tout cas comme je l'ai dit plus haut un simple set parent sur l'app fait l'affaire pas la peine d'ajouter un module supplémentaire pour mettre un message au centre de la fenêtre excel
rien n'empêche de lui redonner le style de W10 me semble til t'avoir montrer comment faire avec dwmapi.dll
@TooFatBoy mes drivers ne sont pas pourris ils fonctionne très bien
cela dit tester avec un!!!! écran normal blablabla n'a aucun intérêt entre nous
ce module a une utilité uniquement si l'on a plusieurs écrans sinon c'est prendre un tracto pour rempoter un géranium
 

Dudu2

XLDnaute Barbatruc
@patricktoulon,
Oui on n'est bien d'accord que l'utilisation de d'un ressource sur les moniteurs n'a pas de grande utilité à partir du moment où le UserForm doit être affiché sur la fenêtre active. Ce serait utile dans le cas où précisément, il faudrait l'afficher sur un moniteur différent.
@Le_Phénomène a donc 2 solultions:
  1. Soit il utilise ton option SetParent() (designe Shell32.dll) puis positionne dans le milieu de la fenêtre
    VB:
    Private Declare PtrSafe Function SetParent Lib "user32" (ByVal hWndChild As LongPtr, ByVal hWndNewParent As LongPtr) As LongPtrPrivate Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
    
    Private Sub UserForm_Activate()
        Dim hwnd As LongPtr
        hwnd = FindWindow(vbNullString, Me.Caption)
        SetParent hwnd, Application.hwnd
        Me.Move (Application.Width - Me.Width) / 2, (Application.Height - Me.Height) / 2
    End Sub

  2. Soit il utilise les coordonnées de la fenêtre (design dwmapi.dll) puis positionne dans le milieu de la fenêtre
    Code:
    Private Sub UserForm_Activate()
        Me.Move ActiveWindow.Left + (ActiveWindow.Width - Me.Width) / 2, _
                ActiveWindow.Top + (ActiveWindow.Height - Me.Height) / 2
    End Sub
Dans les 2 cas il peut supprimer le Caption
 

TooFatBoy

XLDnaute Barbatruc
Soit il utilise les coordonnées de la fenêtre (design dwmapi.dll) puis positionne dans le milieu de la fenêtre
Toutafé. Et c'est bien ce qu'il fait 😉 :
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
Autant faire au plus simple.

Petite question au passage mon cher Dudu2 : que fait le StartUpPosition = 0 ?



Dans les 2 cas il peut supprimer le Caption
Ce que tu appelles le "Caption", est-ce la Barre de titre du UserForm ?
Si oui, quel serait l'intérêt de la supprimer ?
 

patricktoulon

XLDnaute Barbatruc
Toutafé. Et c'est bien ce qu'il fait 😉 :
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
Autant faire au plus simple.
Non pas si excel n'est pas afficher sur l’écran principal
Ce que tu appelles le "Caption", est-ce la Barre de titre du UserForm ?
Si oui, quel serait l'intérêt de la supprimer ?

comme expliqué plus haut si on affilie l'userform à l'app le userform est redessiné comme il est dans le VBE
c'est a dire a minima comme le thème w7 basique et ça peut ne pas plaire
ben on l'enlève on a ainsi le message affiché au centre de l'app ou quel soit dans n'importe quel ecran et
on peut plus le déplacer car pas de barre de titre et quand on bouge la fenêtre excel ben le userform suit

le tout en 3 ligne de code
c'est pas mal avec des drivers graphiques pourris non?
 

Dudu2

XLDnaute Barbatruc
Salut les afficheurs de UserForms,

J'ai amélioré ma petite ressource de Barre de Progression Interruptible (sur option):
pour y ajouter:
- le centrage par défaut dans la fenêtre active
- la possibilité de la positionner Left et Top
- la possibilité de la dimensionner en Width et Height
- la possibilité de désigner la couleur de la barre
- la possibilité de supprimer le Caption (barre de menu système de la fenêtre)

Tous les paramètres sont modifiables en cours d'exécution (à chaque appel) de la barre.

En principe ça devrait convenir à @Le_Phénomène sans avoir à trop bricoler.

Je vous mets le fichier de la ressource en copie (voir post suivant)

Progresssion1.gif


Progresssion2.gif
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Bonjour,

J'ai (encore) modifié le code de la Barre de Progression pour tirer les enseignements de ce sujet qui permet de traiter proprement le cas du retrait du Caption et le cas de son rajout après retrait.

C'est aussi dans cette ressource.

Fichier: voir post suivant.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
Bonjour à tous
perso je vais juste poser une question
il va de soit que j'ai déjà la réponse c'est juste pour mettre en lumière certaines choses
ma question est par exemple (parmi d'autres dans cette démo)
à quoi sert la fonction"IsBordersAndSystemBarRemoved"
et forcement toute les conséquences et dépendances des autres fonctions ou subs dans cette démonstration

SVP réfléchissez bien avant de répondre ;)
c'est dans l'intérêt de tous ceux qui vous lisent
 

Dudu2

XLDnaute Barbatruc
Bonjour @patricktoulon,
Je ne comprends pas bien pourquoi tu poses cette question d'autant que cette fonction ne fait pas partie du code de la barre de progression aussi dans cette ressource.

La fonction à laquelle tu fais référence est maintenant dans cette ressource avec le nom IsUserFormCaptionPresent() et elle retourne True ou False selon que le Caption est présent ou pas dans le UserForm, comme son nom l'indique.

Et donc elle pose problème / question ...
 

Statistiques des forums

Discussions
315 111
Messages
2 116 340
Membres
112 721
dernier inscrit
Ulricn