XL 2016 Quelle API pour savoir si une ListBox (UserForm ou ActiveX) a sa ScrollBar Verticale présente ?

Dudu2

XLDnaute Barbatruc
Bonjour les XLDNautes,

Si on peut, sans API, savoir si une ComboBox a son ascenseur affiché grâce à la différence (ComboBox.ListCount - ComboBox.ListRows) ce n'est pas possible avec les ListBoxes.
Certes on connaît son ListBox.TopIndex mais il n'existe pas de ListBox.BottomIndex.
Un approximation est possible avec la ListBox.Font.Size mais ça reste imprécis.

Reste l'API qui pourrait indiquer la présence d'une Vertical ScrollBar mais mes essais sont restés infructueux.
Merci pour toute suggestion.
 
Solution
pour ce qui est de cette discussion j'ai revue la chose pour les ListBox dans userform et feuille

patricktoulon

XLDnaute Barbatruc
re
attends je teste ta listbox
en attendant
a gauche ta version a droite( la mienne sans aucune api )extrait de la version 5 du hook
1668268113941.png
 

patricktoulon

XLDnaute Barbatruc
Ok merci, 3 pixels de décalage. Pas bon.
Je pense qu'il faut remplacer Top = Top + 17 par Top = Top + 16 pour par Top = Top + 16.5
c'es t pas bon chez moi
de tout facon en aucun cas on ne peut utiliser de chiffre en dur dans le code
ca va chez toi mais ca n'ira pas chez les autres

c'est simple ta listbox dans les properties vbe fait 112.2 de large et et 66.8 de haut ( en points )

chez moi en dpi normale 100 (96) en pixel ça doit donner

112.2*(4*3)=149.6 pixel soit 149 car un demi pixel ce n'existe pas

66.8*(4*3) =89.06 soit 89 car un demie pixel n'existe pas

chez toi
si je ne me trompe pas en dpi 120 (zoom window 125)
tu multiplie ces résultat par 1.25

soit 149*1.25 donc 186,25 pareil les demie byebye !!!
89*1.25=111 , 56 pareil les demie byebye !!!

et si tu veux ma fonction la voila

si tu avais télécharger et regarder mon calendrier tu l'aurais depuis longtemps

j'ai bloqué pour la démo la partie pour le child combo présumé
là on va chercher le rectangle du control lui meme

VB:
Function getControlRectangleForM(obj As Object) As RECT
    Dim LfT As Double, Rgt As Double, Top As Double, P As Object, PInsWidth As Double, PInsHeight As Double, z#
    Dim K As Double, r As RECT, uu, ItemSize#
    LfT = obj.Left: Top = obj.Top: Set P = obj.Parent
    Do
        PInsWidth = P.InsideWidth: PInsHeight = P.InsideHeight: If TypeOf P Is MSForms.Page Then Set P = P.Parent
        K = (P.Width - PInsWidth) / 2: LfT = (LfT + P.Left + K): Top = (Top + P.Top + P.Height - K - PInsHeight)
        If Not (TypeOf P Is MSForms.Frame Or TypeOf P Is MSForms.MultiPage) Then Exit Do
        Set P = P.Parent
    Loop
    With ActiveWindow.Panes(1)
        z = .Parent.Zoom / 100.01
        r.Left = .PointsToScreenPixelsX(LfT / z) - .PointsToScreenPixelsX(0)
        r.Top = .PointsToScreenPixelsY(Top / z) - .PointsToScreenPixelsY(0)
        r.Right = Round(r.Left + (.PointsToScreenPixelsX(obj.Width / z) - .PointsToScreenPixelsX(0)), 2)
        r.Bottom = Round(r.Top + (.PointsToScreenPixelsY(obj.Height / z) - .PointsToScreenPixelsY(0)), 2)
        'If TypeName(obj) = "ComboBox" Then
         'calcul du rectangle présumé du child de la combo
       ' Set uu = USFForm.Controls.Add("forms.label.1", "uu")
        ' With uu
        ' .Height = 1: .Width = 1: .Font.Size = obj.Font.Size: .Font.Name = obj.Font.Name: .Font.Bold = obj.Font.Bold
        ' .Caption = "A": .BorderStyle = 1: .BackColor = vbYellow
        ' .AutoSize = True
        ' ItemSize = .Height - 1
        'End With
        ' USFForm.Remove "uu"
        ' r.Bottom = r.Bottom + (((ItemSize) * obj.ListRows) * Ppx)
        'r.Bottom = r.Bottom + ((ItemSize * (obj.ListRows - IIf(obj.Font.Size < 9, 1, 0)) - 2) * Ppx)
        'r.Top = r.Top + (obj.Height * Ppx)
        'End If

    End With
    getControlRectangleForM = r
End Function
 

Dudu2

XLDnaute Barbatruc
Ok, en dézippant ta boucle Do Loop à 28 instructions par ligne , j'ai compris ce sur quoi je me cassais les dents avec les Pages et MultiPages.
Par contre je ne vois pas ce que le Zoom vient faire dans cette affaire.
Je corrige mon code et je reviens.
 

Dudu2

XLDnaute Barbatruc
faut il que je ré explique ?
Non, pour moi le Pan.PointsToScreenPixels tient compte du zoom, pas besoin d'en rajouter. Mais bon...

Par contre je dois reconnaître que sans ton code sur les Pages & MultiPages je ne m'en serais jamais sorti. Merci pour ce petit trésor de calcul.
J'en ai d'ailleurs reproduit de manière dézippée (pour ma compréhension) , la structure dans mon code.
 

Pièces jointes

  • CheckComputedVersusWindowRECT.xlsm
    55.9 KB · Affichages: 5

patricktoulon

XLDnaute Barbatruc
Non, pour moi le Pan.PointsToScreenPixels tient compte du zoom, pas besoin d'en rajouter. Mais bon...
purée de coquin de sort tu va me rendre chèvre toi

c'est faux ce que tu dis et c'est justement la le problème


Par contre je dois reconnaître que sans ton code sur les Pages & MultiPages je ne m'en serais jamais sorti. Merci pour ce petit trésor de calcul.
et comme tu peux le voir j'utilise des propriété width et height pas des 16.5 ou 17 ou je ne sais quoi
ca c'est universel(du moins pour l'instant) avec les versions récente de excel je pressent un bouleversement

allez j'explique

penons une valeur on va dire 60 (ça c'est en point ) pas compliqué

essayons de convertir en pixel avec prise encompte du zoom et sans le prendre en compte
je te fait donc une demo avec 4 tests
sans prise en charge du zoom
1 en zoom 100%
2 en zoom 80%
3 et en zoom 80% avec prise en charge du zoom dans le calcul
4 et en zoom100% avec prise en charge du zoom dans le calcul

après tu prend ta calculette et tu fait l'operation pour voir qui a raison
VB:
Sub testconvertpixel()
Dim mavaleurPoint, mavaleurPix, z#, texte$
mavaleurPoint = 60
With ActiveWindow.Panes(1)

'test 1
.Parent.Zoom = 100 ''zoom normal  à  100%
mavaleurPix = .PointsToScreenPixelsX(mavaleurPoint) - .PointsToScreenPixelsX(0)
texte = texte & "TEST 1 a zoom 100%--> 60 en pixel font : " & mavaleurPix & vbCrLf & vbCrLf

'test 2
.Parent.Zoom = 80 'zoom   à  80%
mavaleurPix = .PointsToScreenPixelsX(mavaleurPoint) - .PointsToScreenPixelsX(0)
texte = texte & "TEST 2 a zoom 80%--> 60 en pixel font : " & mavaleurPix & vbCrLf & "là  c'est beaucoup moins bien dejà " & vbCrLf & vbCrLf


texte = texte & "maintenant prise en compte du zoom dans le calcul" & vbCrLf & vbCrLf

'test 3 'on inclu le zoom dans le calcul
.Parent.Zoom = 80 'zoom   à  80%
z = .Parent.Zoom / 100
mavaleurPix = Round(.PointsToScreenPixelsX(mavaleurPoint / z) - .PointsToScreenPixelsX(0))
texte = texte & "TEST 3 a zoom 80% inclu dans calcul--> 60 en pixel font : " & mavaleurPix & vbCrLf & "l ah ben oui ca va beaucou mieux  déjà " & vbCrLf & vbCrLf


'test 4 'on inclu le zoom dans le calcul
.Parent.Zoom = 100 'zoom   à  80%
z = .Parent.Zoom / 100
mavaleurPix = Round(.PointsToScreenPixelsX(mavaleurPoint / z) - .PointsToScreenPixelsX(0))
texte = texte & "TEST 4 a zoom 100% inclu dans calcul--> 60 en pixel font : " & mavaleurPix & vbCrLf & "ahh.. ben oui a 80 ou 100 % ca fonctionne bien " & vbCrLf & vbCrLf

End With
MsgBox texte
End Sub
après si tu comprends pas c'est que tu code sans savoir et ou connaître ce que tu utilise
dis moi que j'ai tords ;)
 

Dudu2

XLDnaute Barbatruc
Je ne comprends pas pourquoi tu t'emm... bête avec le Pane(1).PointsToScreenPixelsX(0) !?
Je ne sais pas ce que tu bricoles avec ça mais il n'a rien à faire dans les calculs sinon à t'obliger à introduire le Zoom pour en corriger l'effet délétère. C'est toi qui ne comprends pas.

Pour trouver la position Pixel X d'un Objet, il suffit de faire Pane(1).PointsToScreenPixelsX( Object.Left) quelque soit le Zoom !

Dans ce fichier je positionne le curseur au milieu de la cellule C4 sous différents Zoom.
Nul besoin de bricoler du Zoom et du PointsToScreenPixelsX(0) !
D'ailleurs avec ta méthode je n'arrive pas à positionner correctement.
 

Pièces jointes

  • Classeur1.xlsm
    26.8 KB · Affichages: 3

Statistiques des forums

Discussions
312 215
Messages
2 086 314
Membres
103 176
dernier inscrit
jean.yvesjean.yves