IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Positionner curseur sur une cellule sélectée Windows Excel VBA


Sujet :

Macros et VBA Excel

  1. #921
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    de le savoir directement (toujours avec la même librairie
    si tu l'a pas tu risque pas d'utiliser une autre de ses fonctions

    bon donc avec xp pas de décalage on zappe le moulin pour xp alors

    je suppose que tu n'a pas envie de me donner ce résultat par hasard
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
    Sub test()
         'SM_CXSIZEFRAME 32 Win 95/98 only: Return the width of a thick window frame.
    MsgBox GetSystemMetrics(32)
    'SM_CYSIZEFRAME 33 Win 95/98 only: Return the height of a thick window frame.
    MsgBox GetSystemMetrics(33)
    'SM_CYDLGFRAME 8 Win NT only: Return the height of a window frame having a dialog frame style.
    MsgBox GetSystemMetrics(8)
    'SM_CYBORDER 6 Win NT: Return the height of a window border. Win 95/98: Return the height of a single window border
    MsgBox GetSystemMetrics(6)
    End Sub
      0  1

  2. #922
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    si tu l'a pas tu risque pas d'utiliser une autre de ses fonctions
    Ah ! Encore une lecture en diagonale ....
    C'est pourtant enfantin --->>

    1) la compilation conditionnelle permettra d'éviter de travailler avec un "fantôme" (la totalité du "fantôme")
    2) l'autre fonction de l'Api de Windows permettra (puisque l'on est alors pas dans le cas "fantôme" évité par la compilation conditionnelle) de savoir si Aero (dont on sait qu'il est alors forcément présent) est ou non activé. Et la dll est forcément là (puisque pas dans le cas "fantôme).

    "Elémentaire, Mon cher Watson". Réfléchir avant de se jeter tête baissée dans toutes les directions

    EDIT : et si tout cela échappe à ta perspicacité :
    1) relis mon message 917 :
    J'attends que tout soit définitivement arrêté pour montrer comment. Ce ne sera pas compliqué du tout
    et
    2) contente-toi alors d'attendre (et tu verras bien comment, hein ...)


    EDIT 2 : j'avais zappé ceci :
    je suppose que tu n'a pas envie de me donner ce résultat par hasard
    et le code qui suit ...
    Ah ?
    Il me semble avoir déjà eu l'occasion de te dire que je n'aimais pas certaines manières. Celles, entre autres, qui consistent à dire "teste" ceci ou "teste cela" ou "regarde ceci" ou "regarde cela" sans en exposer ce que c'est censé faire et apporter.
    Tu vas d'abord me dire techniquement et très clairement ce que tu penses que ce code pourrait nous permettre de connaître utilement (qui nous apporterait une indication concernant .... un rectangle étendu créé par aero)
      0  1

  3. #923
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    C'est même encore plus simple (même pas besoin de compilation conditionnelle).
    Une simple gestion d'erreur toute bête fait l'affaire (je viens de le vérifier *****)

    ***** Preuve -->>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Option Explicit
    Private Declare Function fonction_inconnue Lib "librairie_inconnuue" (on_s_en_fiche As Long) As Long
    Dim ret As Long
    
    Private Sub CommandButton1_Click()
        On Error Resume Next
        ret = fonction_inconnue(20)
        On Error GoTo 0
        MsgBox ret
    End Sub
      0  1

  4. #924
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    A Franck.
    Voilà comment je crois comprendre que l'on peut déterminer si Aero (lorsque présent) est ou non activé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Private Const DWM_EC_DISABLECOMPOSITION As Long = 0
    Private Const DWM_EC_ENABLECOMPOSITION As Long = 1
    Private Declare Function DwmEnableComposition Lib "dwmapi" (uCompositionAction As Long) As Long
     
    private sub pour_voir()
      dim ret as long
      ret = (DwmEnableComposition(DWM_EC_DISABLECOMPOSITION)) 
        if ret=0 Then
            MsgBox "désactivé"
        Else
            MsgBox "activé"
        End If
    End Sub
    si pas exactement cela, ce ne doit pas en être très loin ...


    EDIT (pour Franck)
    Et si ce code est bon, je pense qu'il n'est alors pas besoin de tester deux fois (une fois pour vérifier si aero est disponible et l'autre pour voir s'il est activé ou non).
    Je m'explique : je crois avoir compris que lorsque aero (présent) est désactivé, il n'y a pas création d'un "rectangle étendu" et qu'on est alors dans le même cas que sur une machine (XP) sans aero.
    Dès lors, le mécanisme général pourrait être du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ret = 999 'on lui donne une valeur différente de 0 et de 1
      dim ret as long
      on error resume next
        ret = (DwmEnableComposition(DWM_EC_DISABLECOMPOSITION)) 
      on error goto 0
      if ret = 0 or ret = 999 then ' --->> pas de aero ou aero désactivé
        le_rectangle.top = userform1.top ' --->> nos coordonnées restent alors celles de l'userform
        le rectangle.left = userform1.left
      else
         on lance ici le code que 'on connait déjà pour extraire le top et le left du rectange étendu et on en déduit (comme déjà vu) la "correction" à appliquer
      end if
    Je pense que cela devrait parfaitement suffire.



    Amitiés
      0  1

  5. #925
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 816
    Points : 2 954
    Points
    2 954
    Billets dans le blog
    10
    Par défaut
    Bonjour tout le monde,

    @Nicolas :
    En fait, dans ma dernière version, la position de la cellule (fPosCel) était arrondie du fait du typage de cette fonction As RECT.
    J'ai donc, tout simplement créé un nouveau type (myRECT) composé de 4 Double au lieu des Long de RECT.

    @Patrick :
    On s'en fiche un peu de XP car non concerné. Mais tu fais bien de le signaler pour éviter d'éventuelles erreurs.
    Comme le dis Jacques un traitement d'erreur suffira (intégré dans mon code de ce matin).

    @Jacques :
    La fonction DwmEnableComposition, de ce que j'en ai lu et compris, sert à activer ou désactiver DWM.
    Elle ne retourne pas l'activation ou la désactivation d'aero.
    Du moins ton test me retourne systématiquement "activé".
    De toutes façons, le fait de tester le retour de DwmGetWindowAttribute suffit non?
    Comme dit plus tôt si retour.Left = 0 ==> aero non activé.


    En combinant tout, cela nous donne le code suivant :

    Code du Module1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    Option Explicit
     
    Private Enum DWMWINDOWATTRIBUTE
        DWMWA_NCRENDERING_ENABLED = 1
        DWMWA_NCRENDERING_POLICY
        DWMWA_TRANSITIONS_FORCEDISABLED
        DWMWA_ALLOW_NCPAINT
        DWMWA_CAPTION_BUTTON_BOUNDS
        DWMWA_NONCLIENT_RTL_LAYOUT
        DWMWA_FORCE_ICONIC_REPRESENTATION
        DWMWA_FLIP3D_POLICY
        DWMWA_EXTENDED_FRAME_BOUNDS
        DWMWA_LAST
    End Enum
     
    Public Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
     
    Public Type myRECT
        Left As Double
        Top As Double
        Right As Double
        Bottom As Double
    End Type
     
    Private Declare Function DwmGetWindowAttribute Lib "dwmapi.dll" (ByVal hwnd As Long, ByVal dwAttribute As Long, ByRef pvAttribute As Any, ByVal cbAttribute As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
     
    Private Col As Long, Lig As Long
     
    Public Function fPosCel(RngTarget As Range) As myRECT
    Dim LngPane As Long, LngNbPanes As Long, DblPpx As Double, BoolScreenUp As Boolean
     
        If Application.ScreenUpdating = False Then Application.ScreenUpdating = True: BoolScreenUp = True
        DblPpx = fPpx(72)
        LngNbPanes = ActiveWindow.Panes.Count
        For LngPane = 1 To LngNbPanes
            With ActiveWindow.Panes(LngPane)
                If Not Intersect(RngTarget, .VisibleRange) Is Nothing Then
                    fPosCel.Left = .PointsToScreenPixelsX(RngTarget.Left) / DblPpx
                    fPosCel.Top = .PointsToScreenPixelsY(RngTarget.Top) / DblPpx
                    'fPosCel.Right = RngTarget.Width
                    'fPosCel.Bottom = RngTarget.Height
                    Exit For
                End If
            End With
        Next
        If BoolScreenUp Then Application.ScreenUpdating = False
    End Function
     
    Public Function fMarges(Usf_Caption As String, Usf_Left As Double, Usf_Top As Double) As RECT
    Dim LngResult As Long, LngHwnd As Long, DblPpx As Double, BoolFreeze As Boolean
     
        DblPpx = fPpx(72)
        If ActiveWindow.FreezePanes = True Then BoolFreeze = True: Call sLibere(False)
        LngHwnd = FindWindow(vbNullString, Usf_Caption)
        On Error Resume Next
        LngResult = DwmGetWindowAttribute(LngHwnd, DWMWA_EXTENDED_FRAME_BOUNDS, fMarges, LenB(fMarges))
        On Error GoTo 0
        If fMarges.Left <> 0 Then
            fMarges.Left = Usf_Left - (fMarges.Left / DblPpx)
            fMarges.Top = Usf_Top - (fMarges.Top / DblPpx)
        End If
        If BoolFreeze Then Call sRefige(True)
    End Function
     
    Private Function fPpx(Nb As Long) As Double
     
        With CreateObject("WScript.Shell")
            fPpx = .RegRead("HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI") / Nb
        End With
    End Function
     
    Private Sub sLibere(Comment As Boolean)
     
        With ActiveWindow
            Col = .SplitColumn
            Lig = .SplitRow
            .FreezePanes = Comment
        End With
    End Sub
     
    Private Sub sRefige(Comment As Boolean)
     
        With ActiveWindow
            .SplitColumn = Col
            .SplitRow = Lig
            .FreezePanes = Comment
        End With
    End Sub
    Code du bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Private Sub CommandButton3_Click()
    Dim R As RECT, myR As myRECT
    'Dim Message As String
     
        Application.ScreenUpdating = False
        myR = fPosCel(ActiveCell)
        With UserForm2
            .StartUpPosition = 0
            .Show 0
            .Top = myR.Top
            .Left = myR.Left
            'Message = "Avant marges : Top = " & myR.Top & "    Left = " & myR.Left & vbCrLf
        End With
        R = fMarges(UserForm2.Caption, UserForm2.Left, UserForm2.Top)
        'Message = Message & "Marges  : Top = " & R.Top & "    Left = " & R.Left & vbCrLf
        With UserForm2
            .Top = UserForm2.Top + R.Top
            .Left = UserForm2.Left + R.Left
        'Message = Message & "Finalement  : Top = " & .Top & "    Left = " & .Left
        End With
        Application.ScreenUpdating = True
        'MsgBox Message
    End Sub
    En cas de souci, affichez le message commenté dans le code du bouton.
    Cela permettra d'avoir un aperçu de l'erreur...

    Bon, à vrai dire, il reste du travail... Beaucoup !!
    Mais bon, comme je suis passé par ici je ne vous quitte plus
    J'y retourne en attendant de vos nouvelles.
      0  1

  6. #926
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 816
    Points : 2 954
    Points
    2 954
    Billets dans le blog
    10
    Par défaut
    Pour Jacques :
    Cette fonction me retourne systématiquement la valeur -2147024809, que aéro soit ou non activé sur le pc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Private Const DWM_EC_DISABLECOMPOSITION As Long = 0
    Private Const DWM_EC_ENABLECOMPOSITION As Long = 1
    Private Declare Function DwmEnableComposition Lib "dwmapi.dll" (uCompositionAction As Long) As Long
     
    Private Sub pour_voir()
      Dim ret As Long
      On Error Resume Next
        ret = (DwmEnableComposition(DWM_EC_ENABLECOMPOSITION))
      Debug.Print ret
        ret = (DwmEnableComposition(DWM_EC_DISABLECOMPOSITION))
      Debug.Print ret
      On Error GoTo 0
    End Sub
    EDIT :
    test si aero est activé (vu ICI)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Private Enum BOOL
        FALSE_
        TRUE_
    End Enum
    #If False Then
        Dim FALSE_, TRUE_
    #End If
    Private Declare Function DwmIsCompositionEnabled Lib "dwmapi.dll" (ByRef pfEnabled As BOOL) As Long
     
    Sub test()
    Dim BOOLAero As BOOL
    Const S_OK = 0&
        If DwmIsCompositionEnabled(BOOLAero) = S_OK And BOOLAero = TRUE_ Then
        'aero activé
        Else
        'aero désactivé
        End If
    End Sub
      0  1

  7. #927
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    Merci Franck

    Lorsque tout sera concrétisé et vérifié satisfaisant pour toutes les configurations :
    Peux-tu déposer une contribution à ce sujet ?
    Si tu le fais :
    - essaye de bien séparer la partie positionnement précis, à des coordonnées spécifiées (quelles qu'elles soient et où qu'elles soient - sur une feuille ou n'importe quoi d'autre) , de l'angle supérieur gauche "apparent" (y compris ses bordures éventuellement ajoutées par aero) du reste (détermination des coordonnées/écran de l'angle supérieur gauche d'une cellule spécifiée.
    Car ce sont deux choses distinctes.
    Je dirais d'ailleurs in fine (ici et non dans la contribution que tu accepterais de faire) à ce propos pourquoi, en ce qui concerne un placement sur une feuille de calcul, il est futile et maladroit de placer l'userform SUR une cellule. Ce sera là le message correspondant à une promesse que j'avais faite bien plus haut dans cette discussion.
    Le seul intérêt réel de CETTE discussion en ce qui concerne autre chose que le placement à des coordonnées précises étant la détermination des coordonnées en pixels d'une cellule sur l'écran.
    Amitiés
      0  1

  8. #928
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    oui la gestion d'erreur peut être bien mais il est bien de savoir pour quoi l'erreur car elle peut se produire pour diverses raisons
    on peut dans le gestion d'erreur corriger le cas échéant si librairie présente mais que le err.description ou errur.number <>53

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Private Declare Function nimoportequoi Lib "existepas.dll" (ByVal hwnd As Long, ByVal dwAttribute As Long, ByRef pvAttribute As Any, ByVal cbAttribute As Long) As Long
    Sub test()
     On Error GoTo gestionerr
     i = nimoportequoi(handleusf, DWMWA_EXTENDED_FRAME_BOUNDS, rectangle, LenB(rectangle))
    Exit Sub
    gestionerr:
    If Err.Number = 53 Then MsgBox " votre system ne possède pas ce fichier DLL " Else MsgBox Error.Description
    End Sub
    apres sincèrement j'aime pas trop le "on error...."

    après avec operating system qui nous donne la version windows on peut faire simplement un "if version then "
    du genre ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Public Function Marges(Lcaption$, L#, T#, ppx#) As RECT
        Dim rectangle As RECT, handleusf As Long    ' ----->> le rectangle étendu que l'on veut extraire (aero, donc)
        Version = CStr(Val(Split(Application.OperatingSystem, " ")(3)))
        Marges.Left = 0: Marges.Top = 0
        If Version > 6 Then
            handleusf = FindWindow(vbNullString, Lcaption)
            DwmGetWindowAttribute handleusf, DWMWA_EXTENDED_FRAME_BOUNDS, rectangle, LenB(rectangle)
            Marges.Left = IIf(rectangle.Left / ppx <> 0, L - (rectangle.Left / ppx), 0)
            Marges.Top = IIf(rectangle.Top / ppx <> 0, T - (rectangle.Top / ppx), 0)
        End If
    End Function
      0  1

  9. #929
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    Si tu veux éviter la gestion d'erreur, il vaudrait alors mieux utiliser la compilation conditionnelle, Patrick !
    Ceci étant dit, la gestion d'erreur est ici plus souhaitable et légère et n'est pas un sacrilège du tout, dès lors qu'elle ne correspond pas à la détermination d'une erreur de code, mais à un impondérable autre.

    Et tel qu'encadré, l'appel de la fonction ne peut générer d'autre erreur que l'absence de la fonction
    Et par ailleurs (si vraiment tu veux identifier le code de l'erreur), une gestion plus complète de l'erreur le permet . Mais ce serait ici inutile !
      0  1

  10. #930
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    un petit oubli dans mon if version en effet les Windows 64 tournent avec office 64 renvoient 0

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Version = 0 Or Version > 6 Then
      0  1

  11. #931
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 816
    Points : 2 954
    Points
    2 954
    Billets dans le blog
    10
    Par défaut
    Ecrire une contribution, pourquoi pas.
    Je veux bien participer à l'écriture d'un article à ce sujet, mais le faire seul...

    Bon quoiqu'il en soit, pour que tous puissent tester, voici le dernier "jus de code" :

    Modifications apportées :
    1. des petites fonctions gèrent les cas d'erreurs dûes à l'api,
    2. type myRECT ==> pour une précision niveau Double de l'emplacement de la cellule
    3. tests ajoutés : Application.WindowState et TestWindow (si toutes invisibles...)
    4. Const X et Y par défaut...



    Module1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    Option Explicit
     
    Private Enum DWMWINDOWATTRIBUTE
        DWMWA_NCRENDERING_ENABLED = 1
        DWMWA_NCRENDERING_POLICY
        DWMWA_TRANSITIONS_FORCEDISABLED
        DWMWA_ALLOW_NCPAINT
        DWMWA_CAPTION_BUTTON_BOUNDS
        DWMWA_NONCLIENT_RTL_LAYOUT
        DWMWA_FORCE_ICONIC_REPRESENTATION
        DWMWA_FLIP3D_POLICY
        DWMWA_EXTENDED_FRAME_BOUNDS
        DWMWA_LAST
    End Enum
     
    Private Enum BOOL
        FALSE_
        TRUE_
    End Enum
    '#If False Then
    '    Dim FALSE_, TRUE_
    '#End If
     
    Public Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
     
    Public Type myRECT
        Left As Double
        Top As Double
        Right As Double
        Bottom As Double
    End Type
     
    Private Declare Function DwmGetWindowAttribute Lib "dwmapi.dll" (ByVal hwnd As Long, ByVal dwAttribute As Long, ByRef pvAttribute As Any, ByVal cbAttribute As Long) As Long
    Private Declare Function DwmIsCompositionEnabled Lib "dwmapi.dll" (ByRef pfEnabled As BOOL) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
     
    Private Col As Long, Lig As Long
     
    Private Const X_PAR_DEFAUT As Long = 0
    Private Const Y_PAR_DEFAUT As Long = 0
    Private Const CONV_PPX As Long = 72
     
    Public Function fPosCel(RngTarget As Range, BoolRetour As Boolean) As myRECT
    Dim DblPpx As Double
    Dim LngPane As Long, LngNbPanes As Long
    Dim BoolScreenUp As Boolean
     
        'TESTS-----------------------------------------
        If Application.WindowState = xlMinimized Or fTestWindow = False Then
            fPosCel.Top = Y_PAR_DEFAUT
            fPosCel.Left = X_PAR_DEFAUT
            Exit Function
        End If
        If Application.ScreenUpdating = False Then
            Application.ScreenUpdating = True
            BoolScreenUp = True
        End If
        '/TESTS-----------------------------------------
     
        BoolRetour = True
        DblPpx = fPpx(CONV_PPX)
        LngNbPanes = ActiveWindow.Panes.Count
        For LngPane = 1 To LngNbPanes
            With ActiveWindow.Panes(LngPane)
                If Not Intersect(RngTarget, .VisibleRange) Is Nothing Then
                    fPosCel.Left = .PointsToScreenPixelsX(RngTarget.Left) / DblPpx
                    fPosCel.Top = .PointsToScreenPixelsY(RngTarget.Top) / DblPpx
                    Exit For
                Else
                    fPosCel.Top = Y_PAR_DEFAUT
                    fPosCel.Left = X_PAR_DEFAUT
                End If
            End With
        Next
        If BoolScreenUp Then Application.ScreenUpdating = False
    End Function
     
    Public Function fMarges(Usf_Caption As String, Usf_Left As Double, Usf_Top As Double) As RECT
    Dim DblPpx As Double
    Dim LngResult As Long, LngHwnd As Long
    Dim BoolFreeze As Boolean
     
        DblPpx = fPpx(CONV_PPX)
        If ActiveWindow.FreezePanes = True Then BoolFreeze = True: Call sLibere(False)
        LngHwnd = fHwndFenetre(Usf_Caption)
        If LngHwnd = -1 Then
            'retourne 0 si hWnd pas trouvé
            fMarges.Left = 0
            fMarges.Top = 0
            GoTo Defreeze
        End If
        LngResult = fCalculeMarges(fMarges, LngHwnd)
        If LngResult = -1 Then
            'retourne 0 si XP
            fMarges.Left = 0
            fMarges.Top = 0
            GoTo Defreeze
        End If
        If fIsAeroActivated Then
            fMarges.Left = Usf_Left - (fMarges.Left / DblPpx)
            fMarges.Top = Usf_Top - (fMarges.Top / DblPpx)
        Else
            'retourne 0 si aero désactivé
            fMarges.Left = 0
            fMarges.Top = 0
        End If
    Defreeze:
        If BoolFreeze Then Call sRefige(True)
    End Function
     
    Private Function fTestWindow() As Boolean
    Dim WinDo As Window, BoolTestWindow As Boolean
     
        For Each WinDo In Application.Windows
            If WinDo.Visible = True Then
                BoolTestWindow = True
                Exit For
            End If
        Next WinDo
        fTestWindow = BoolTestWindow
    End Function
     
    Private Function fPpx(Nb As Long) As Double
     
        With CreateObject("WScript.Shell")
            fPpx = .RegRead("HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI") / Nb
        End With
    End Function
     
    Private Function fHwndFenetre(Usf_Caption As String) As Long
     
        On Error Resume Next
        fHwndFenetre = FindWindow(vbNullString, Usf_Caption)
        If Err <> 0 Then
            Err.Clear
            fHwndFenetre = -1
        End If
    End Function
     
    Private Function fCalculeMarges(M As RECT, LngHwnd As Long) As Long
     
        On Error Resume Next
        fCalculeMarges = DwmGetWindowAttribute(LngHwnd, DWMWA_EXTENDED_FRAME_BOUNDS, M, LenB(M))
        If Err <> 0 Then
            Err.Clear
            fCalculeMarges = -1
        End If
    End Function
     
    Private Function fIsAeroActivated() As Boolean
    Dim BOOLAero As BOOL
    Const S_OK = 0&
     
        On Error Resume Next
        fIsAeroActivated = (DwmIsCompositionEnabled(BOOLAero) = S_OK And BOOLAero = TRUE_)
        If Err <> 0 Then
            Err.Clear
            fIsAeroActivated = False
        End If
    End Function
     
    Private Sub sLibere(Comment As Boolean)
     
        With ActiveWindow
            Col = .SplitColumn
            Lig = .SplitRow
            .FreezePanes = Comment
        End With
    End Sub
     
    Private Sub sRefige(Comment As Boolean)
     
        With ActiveWindow
            .SplitColumn = Col
            .SplitRow = Lig
            .FreezePanes = Comment
        End With
    End Sub
    Bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    Sub CommandButton3_Click()
    Dim R As RECT, myR As myRECT, BoolRetour As Boolean
    'Dim Message As String
        Application.ScreenUpdating = False
        myR = fPosCel(ActiveCell, BoolRetour)
        With UserForm2
            .StartUpPosition = 0
            .Show 0
            .Top = myR.Top
            .Left = myR.Left
            'Message = "Avant marges : Top = " & myR.Top & "    Left = " & myR.Left & vbCrLf
        End With
        If BoolRetour = True Then
            R = fMarges(UserForm2.Caption, UserForm2.Left, UserForm2.Top)
            'Message = Message & "Marges  : Top = " & R.Top & "    Left = " & R.Left & vbCrLf
            With UserForm2
                .Top = UserForm2.Top + R.Top
                .Left = UserForm2.Left + R.Left
            'Message = Message & "Finalement  : Top = " & .Top & "    Left = " & .Left
            End With
        End If
        Application.ScreenUpdating = True
        'MsgBox Message
    End Sub
      0  1

  12. #932
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    Je veux bien participer à l'écriture d'un article à ce sujet, mais le faire seul...
    tu ne serais pas "seul".
    J'accepterais assez volontiers de collaborer par MP à la rédaction.
    Mais je ne veux pas (je n'ai même pas aero) "déposer" moi-même, Franck.
      0  1

  13. #933
    Membre extrêmement actif Avatar de mjpmjp
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2012
    Messages
    1 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hautes Alpes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2012
    Messages : 1 133
    Points : 1 441
    Points
    1 441
    Par défaut
    bonjour,
    j'attends également une contribution orient thé ... Patrick / Nicolas ...
    autre concept ...

    @+JP
      2  3

  14. #934
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    Bonjour a tous

    je viens de comprendre chez moi une chose que l'on arrivait pas a saisir jusqu'à maintenant

    on s'était rendu compte que selon les colonnes c'était un peu décalé et cela même avec DWM

    alors comptez le nombre de colonne entières que vous avez en visuel a l'écran (celles que l'on voit entièrement!!!)

    si le nombre est impair enlevez en une
    divisez par deux sur la colonne obtenue mettez lui une bordure gauche(toute la colonne )

    maintenant faite pareil pour les ligne mais pas par pair/impair mais groupe de 5 ligne et incluez le heading(ligne ou il y a les lettres de colonne) aussi (il subit le zoom)

    exemple si vous en avez de 16 a 19 de visible on prendra 15 et divisez par 3

    mettez une bordures top sur ces lignes obtenue

    voila nous avons notre grille d'erreur

    en effet l'useform sur chaque cellule touchant une de ces lignes soit par le top soit par le left serra décalé
    Nom : Capture.JPG
Affichages : 301
Taille : 190,7 Ko
    Nom : Capture1.JPG
Affichages : 323
Taille : 99,3 Ko
      0  1

  15. #935
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    Bonjour Patrick
    Et ce que moi, j'ai compris depuis longtemps (47 pages !) c'est que tu "comprends" trop souvent (et chaque fois avec la même "assurance") des choses diverses et variées, qui sont aussi "changeantes" que tes réactions non moins souvent hâtives, voire carrément impulsives..
    Je crois (toi non ?) qu'il sera bien plus sage d'attendre les retours des uns et des autres, après qu'ils auront fait des essais.

    EDIT : une chose est plus que certaine.
    Les résultats (le rectangle étendu) des fonctions de la librairie dwmapi.dll s'appliquent à des coordonnées à l'écran et ignorent dès lors tout le reste (zoom ou pas, Excel ou pas .. je te l'ai déjà dit).
    Si tu insistes avec cette nouvelle "conviction", tu remets alors toi-même en cause (tu les contredis carrément) tes convictions précédentes et affichées avec force également sur la fiabilité (que tu affirmais) de PointsToScreenPixelsX/Y
      0  1

  16. #936
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 816
    Points : 2 954
    Points
    2 954
    Billets dans le blog
    10
    Par défaut
    Bonjour Patrick, Jacques, tout le monde,

    Je n'ai constaté, jusqu'à présent, aucun décalage, ni vertical ni horizontal, sur 2007 et 2010.

    Reste, pour moi, un point à éclaicir :

    extrait de l'aide en ligne :
    Méthode Window.PointsToScreenPixelsX :
    Convertit une mesure horizontale de points (coordonnées du document) en pixels d'écran (coordonnées de l'écran).
    Renvoie la mesure convertie en tant que valeur de type Long
    Si la mesure est convertie en Long cela ne pourrait-il pas créer de tout petits décalages (de l'ordre d'un pixel) ?
      0  1

  17. #937
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    Bonjour Franck

    Cet aspect-là ne peut être systématiquement écarté, mais remet alors en cause la fiabilité et la précision absolues de PointsToScreenPixelsX/Y.
    Si tu remontes plus haut dans ce fatras désordonné qu'est devenue, sur 47 pages, cette discussion où il est maintenant très difficile de retrouver tel ou tel autre message, tu trouveras l'un de mes messages (où, dans ce brouillon ?) où j'exposais que des tests faits par une "équipe" avaient mis en exergue, dans certains cas, un "petit décalage" à l'issue de la seule utilisation de PointsToScreenPixelsX/Y.
    Cet aspect avait été mis en doute par Patrick, qui demandait de lui donner un exemple de ces cas. je lui ai répondu que ces décalages observés fortuitement avaient été reportés mais sans donner lieu à l'établissement d'un relevé de ces cas.

    Amitiés.
      0  1

  18. #938
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 816
    Points : 2 954
    Points
    2 954
    Billets dans le blog
    10
    Par défaut
    Oui Jacques, je me rappelle que tu as déjà abordé ce souci.
    Mais, quoiqu'il arrive, ce décalage devrait être marginal et quasi-invisible...

    Supposons un arrondi au pixel supérieur (ou inférieur).
    Cela signifie un décalage maxi d'un demi pixel.
    Pondéré par le coefficient du DPI (sur mon pc 1,3333333333), cela signifie que j'observerai un décalage de 0,375 pixel.
    Ce qui, si je ne me suis pas trompé (dans le cas contraire dis le moi car cela signifierai que je n'ai pas compris la conversion Pt/Px), représente un décalage de 0,009921875 centimètre.
      0  1

  19. #939
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 430
    Points
    12 430
    Par défaut
    Tout-à-fait, Franck Patrick
    Je partage totalement ton point de vue sur la valeur arithmétique minuscule du décalage éventuel.

    Un seul doute subsiste (le même que nous avions eu en "équipe") : le pixel étant la plus petite surface "dessinable", où sont dessinées ceux dont la valeur n'est pas entière ?

    Ceci étant dit : le décalage que l'on voit sur la capture d'écran montrée par Patrick paraît bien supérieur à un seul pixel . Et je ne vois alors pas d'explication logique, si l'on écarte l'hypothèse d'une modification (une autre "banane" ?) faite au code que tu as montré

    A moins (bien plus vraisemblable) que quelqu'un persiste à utiliser une autre "méthode" n'ayant rien à voir avec ton code et que la capture d'écran corresponde à cette autre "méthode"
      0  1

  20. #940
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 816
    Points : 2 954
    Points
    2 954
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par unparia Voir le message
    Tout-à-fait, Patrick
    Euh... Moi c'est Franck en fait

    Citation Envoyé par unparia Voir le message
    Ceci étant dit : le décalage que l'on voit sur la capture d'écran montrée par Patrick paraît bien supérieur à un seul pixel . Et je ne vois alors pas d'explication logique, si l'on écarte l'hypothèse d'une modification (une autre "banane" ?) faite au code que tu as montré

    A moins (bien plus vraisemblable) que quelqu'un persiste à utiliser une autre "méthode" n'ayant rien à voir avec ton code et que la capture d'écran corresponde à cette autre "méthode"
    Je souhaiterai en avoir le coeur net.
    Donc, Patrick, stp, peux tu me faire passer le classeur ou tu constates ce décalage?
    Disposant, chez moi, d'Excel 2007, je pourrais ainsi confirmer (ou infirmer) ce décalage.
      0  1

Discussions similaires

  1. se positionner sur une cellule
    Par titemireille dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 28/01/2008, 19h07
  2. cliquer sur une cellule qui m'ouvre un autre fichier excel
    Par booskap dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 17/08/2007, 11h08
  3. [VBA-Excel] DblClick sur une cellule
    Par marsupilami34 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 04/01/2007, 10h51
  4. [VBA-Excel]Supprimer une colonne entiere basee sur une cellule
    Par Tartenpion dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 05/10/2006, 22h08
  5. [Vba-Excel] Récupérer événement sur une cellule
    Par steps5ive dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 26/04/2006, 20h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo