XL 2016 Quoi de moins simple que de déterminer le RECT d'une fenêtre ? Fichier pour test...

Dudu2

XLDnaute Barbatruc
Bonjour,

Pour des raisons qui m'échappent, les coordonnées d'une fenêtre ont des valeurs farfelues lorsque cette fenêtre est maximisée.
Ainsi:
VB:
With ActiveWindow
    .Left
    .Top
    .Width
    .Height
End With
ne correspondent pas à la réalité, du moins celle qui pourrait servir à position un UserForm aux limites de la fenêtre pas exemple.

Aussi, j'ai dû passer par de l'API pour déterminer l'exact RECT (pixels) d'une fenêtre qui doit rester valide en multi-moniteurs.
Et bingo, bug excel (chez moi en tous cas) lorsque la TaskBar n'est pas en bas sur la fonction API GetClientRect() qui retourne 1 pixel de moins que prévu en Bottom !

Alors j'ai 2 versions de cette fonction utilisateur GetWindowExactRECT et GetWindowExactRECTSimple et j'aimerais que quelques XLDNautes dévoués aux causes perdues fassent le test suivant.
  1. Lancer le fichier ci-dessous
  2. Maximiser la fenêtre Excel si elle ne l'est pas déjà
  3. Pour chaque position de barre des tâches en bas, à gauche, en haut, à droite
    a) - Vérifier que les 2 résultats affichées des RECT de la fenêtre sont identiques
    b) Vérifier qu'ils sont cohérents avec la dimension de l'écran en pixels
Merci par avance.
 

Pièces jointes

  • Test WindowExactRECT.xlsm
    33.8 KB · Affichages: 6
Solution
C'est ça, en fait ça n'a pas tellement de sens de chercher ou d'utiliser le RECT de la fenêtre.
Car en Maximisé, si Excel dit que Left et Top c'est -8 ou -9 c'est que ce sont les valeurs telles qu'il les gère.
Cependant, ce RECT est inexploitable pour positionner un UserForm.

Le seule chose qui soit exploitable c'est le RECT de la fenêtre corrigé des marges qu'on trouve en calculant la différence de largeur et de hauteur entre le GetWindowRECT et le GetClientRECT corrigé du potentiel bug Excel sur le ClientRECT.Bottom quand la fenêtre est maximisée et la barre des tâches pas en bas ou en antohide.
Sans bug Excel c'est moins amusant !

C'est ce que font maintenant la fonction...

Nicolas JACQUIN

XLDnaute Impliqué
Supporter XLD
Bonjour Dudu2,

Si c'est ce que à quoi je pense et d'on ça a fait tourner la tête à certains,
regarde cette différence, si c'est ce dont à quoi je pense.
  • GetWindowRect donne la position de toute la fenêtre (bordures incluses).
  • GetClientRect donne les dimensions internes de la fenêtre, sans bordures.
Pas de bug de mon coté mais valeur différente aussi, c'est normal.

A bientôt.
Nicolas
 

patricktoulon

XLDnaute Barbatruc
bonsoir
c'est pas un truc farfelu c'est le moins pire des pires en fait
pour des raisons de rétrocompatibilité
quand tu va jouer avec les api le activewindow c'est la fenêtre excel mais pour excel c'est la partie grille avec les headers et la statusbar

et oui avant sur excel 2007 on pouvait détacher ce activewidow et même en afficher 2 dans la même fenêtre excel c’était vraiment des fenêtres fille modifiables en taille

alors que depuis 2010 ce n'est plus possible les activewindow sont dessinée avec la totale de la fenêtre excel

c'est cette gestion qui a changé
 

Dudu2

XLDnaute Barbatruc
Merci @Nicolas JACQUIN pour ton commentaire.
Merci @ChTi160 pour ton retour.
Merci @patricktoulon pour ton explication.

@Nicolas JACQUIN, ce n'est pas aussi simple car comment expliquer que (chez moi):
  • Fenêtre maximisée + barre des tâches en bas
    - Marges en X = 18 (9 + 9) pixels
    - Marges en Y = 18 (9 + 9) pixels

  • Fenêtre maximisée + barre des tâches en haut, à gauche, à droite
    - Marges en X = 18 (9 + 9) pixels
    - Marges en Y = 19 (9 + 10) pixels

  • Fenêtre normale (non maximisée)
    - Marges en X = 2 (1 + 1) pixels
    - Marges en Y = 2 (1 + 1) pixels
Les marges étant la différence entre GetWindowRECT et GetClientRect.
En fait les "vraies" marges sont les 2 pixels, le reste n'est pas cohérent.
 

Pièces jointes

  • Test Marges.xlsm
    21.4 KB · Affichages: 0

patricktoulon

XLDnaute Barbatruc
re ben c'est normal
la fenêtre excel est une plaque( on va parler comme ça)
si tu fait un getwindowrect tu aura le rect de la window classe XLMAIN par rapport a la plaque de l’écran
si tu fait un GetClientRect tu a le rect de la fenêtre excel soit la window classe EXCEL2 par rapport à la plaque XLMAIN donc certainement les bordure de quelque pixels en moins
me semble t il t avoir donné un code pour le constater

Alors qu'avant sur 2007 et inférieur la classe EXCEL2 correspondait a l'activewindow de excel
c'est a dire les headings , la grille et la status bar et les tab onglet

depuis 2010 cette partie c'est la classe EXCEL7

POUR TE DONNER UNE IDEE DU PROBLÈME
SI TU AFFICHE dans une 2d fenêtre la feuille 2avec le bouton affichage dans le ruban
avant ça restait dans la même fenêtre excel sur 2007 donc le getwindowrect sur le application.hwnd se faisait impec

va faire un getwindowrect maintenant sur le application.hwnd en ayant 2 fenêtres d'affichée
ça va pas être triste

j'espère que ces explications seront suffisantes pour te faire comprendre que tout ce que tu peux obtenir n'est qu'une approximation et combien même soit elle excellente mais ne sera jamais juste partout
pour la simple raison c'est que ces api n’atteignent pas les filles il faut d'abords aller chercher la fille
et passer son handle dans le getrect
voila
 

Dudu2

XLDnaute Barbatruc
En réalité, les "vraies" marges de la Window (on a trouvé 1 pixel par différence entre GetWindowRECT et GetClientRect) correspondent aux SM_CXBORDER et SM_CYBORDER du GetSystemMetrics().
Donc jusque là tout va bien pour quand la fenêtre n'est pas maximisée.

Maintenant j'ai un problème philosophique (et oui, ça m'arrive de penser comme Platon ou Socrate surtout après le pastis).

Que dois-je vraiment retourner avec un GetWindowExactRECT ? Le RECT externe ou le RECT interne de la Window ?

En fait ce qui nous intéresse principalement, c'est le placement d'un objet comme le UserForm.
En regardant au microscope l'alignement du UserForm démargé, c'est le RECT interne qui nous intéresse.

Et donc le nom GetWindowExactRECT n'est plus vraiment judicieux ? Comment l'appeler ?
 

Pièces jointes

  • Test WindowExactRECT.xlsm
    51.4 KB · Affichages: 0

patricktoulon

XLDnaute Barbatruc
En réalité, les "vraies" marges de la Window (on a trouvé 1 pixel par différence entre GetWindowRECT et GetClientRect) correspondent aux SM_CXBORDER et SM_CYBORDER du GetSystemMetrics().
Donc jusque là tout va bien pour quand la fenêtre n'est pas maximisée.
Ce n'est pas tout à fait exact même si ça tombe presque pile poil dans tes calculs

te souviens tu dans mon calendar ma fonction place userform
comment je fait pour avoir la position écran d'un control en remontant les parents et en ajoutant le left et top
par rapport au parent jusqu'au userform
et bien avec tes rect c'est la même chose
ton xlmain est a -9 chez moi -8 la fenêtre des onglet ruban est à une distance de left et top de la XLMAIN on ajoute
ainsi que la bordure du parent si bien qu'a la fin en maximisé on tombe à zero

pour info chez moi la différence entre les deux rect c'est 2
 

patricktoulon

XLDnaute Barbatruc
j'ai refait l’expérience
c'est bien ça
l'application XLMAIN
la fille EXCEL2
la file de excel2msocommandbar -8--4--4=0
1734730720721.png

si je place un userform sans caption à ces coordonnées
1734730870809.png

les chiffres sont justes
 

Dudu2

XLDnaute Barbatruc
C'est ça, en fait ça n'a pas tellement de sens de chercher ou d'utiliser le RECT de la fenêtre.
Car en Maximisé, si Excel dit que Left et Top c'est -8 ou -9 c'est que ce sont les valeurs telles qu'il les gère.
Cependant, ce RECT est inexploitable pour positionner un UserForm.

Le seule chose qui soit exploitable c'est le RECT de la fenêtre corrigé des marges qu'on trouve en calculant la différence de largeur et de hauteur entre le GetWindowRECT et le GetClientRECT corrigé du potentiel bug Excel sur le ClientRECT.Bottom quand la fenêtre est maximisée et la barre des tâches pas en bas ou en antohide.
Sans bug Excel c'est moins amusant !

C'est ce que font maintenant la fonction GetClientFromWindowRECT du fichier ci-dessous.

Fichier modifié 21/12/2024 23h22
 

Pièces jointes

  • Test GetClientFromWindowRECT.xlsm
    55.5 KB · Affichages: 0
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
Bonjour @Dudu2
C'est ça, en fait ça n'a pas tellement de sens de chercher ou d'utiliser le RECT de la fenêtre.
Car en Maximisé, si Excel dit que Left et Top c'est -8 ou -9 c'est que ce sont les valeurs telles qu'il les gère.
Cependant, ce RECT est inexploitable pour positionner un UserForm.
Autant je comprenais le besoins de déterminer le rectangle du visibleRange
  • pour y placer et dimensionner un userform (dimension extra) dans ce rectangle
  • pour y placer un object(shape ou autre) ( dimension intra(zoom a prendre en compte)

Autant là je comprends pas le besoins
tu a dispo et en point le left/top/width/height en points
nous savons que maximisé on est a moins -9 ou -8 et peut être autres
en maximisé c'est 0 pour le top et left c'est tout
et pour tout te dire au pire si tu tiens vraiment à avoir un rect en pixel
tu a les getSystemmetrics 0 et 1 qui te donne le width et height de l'écran
et les données sont bonnes
donc
  • rect.top=0
  • rect.left=0
  • rect.right=GetSystemMetrics(0)
  • rect.bottom=GetsystemMetrics(1)
le tout converti en points

et non maximisé
rect.top=app.top
rect.left=app.left
rect.right=app.left+app.width
rect.bottom=app.top+app.height
converti en pixel ou pas selon le besoin
et c'est tout

et je dirais même mieux
si tu tiens Absolument a faire des getwindowrect en mode maximisé
fait le tout simplement sur la taskbar et soustrait aux getsystemmetrics
là tu aura des dimensions justes et qu'importe la position de la taskbar

à méditer ;)
Patrick
 

Statistiques des forums

Discussions
315 088
Messages
2 116 089
Membres
112 658
dernier inscrit
doro 76