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

VBA Access Discussion :

Ouvrir une application sur Le 2ème écran. [AC-2003]


Sujet :

VBA Access

  1. #1
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    230
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 230
    Points : 129
    Points
    129
    Par défaut Ouvrir une application sur Le 2ème écran.
    Bonjour à tous,

    Le titre de mon post ne reflète pas complètement mon problème mais je n'ai pas trouvé mieux...

    J'ai une application qui utilise la bibliothèque ClgDiPlus développé par Arkham46. Cette application a tous ses formulaires personnalisés visuellement et lors de son utilisation la fenêtre Access n'est pas visible. (voir fichier joint)

    Les utilisateurs de l'application ont tous 2 écrans. Certains utilisateurs souhaitent que l'application s'ouvre à chaque fois sur le 2ème écran.

    Pour cela je voudrais utiliser un autre code qu'Arkham46 propose ICI. Il permet facilement de décider sur quel écran l'application doit s'ouvrir.

    Voici le code dans le module :

    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
    Option Compare Database
    Option Explicit
     
    Private Const SM_CMONITORS As Long = 80&
    Private Const SWP_NOSIZE As Long = &H1
    Private Const SWP_NOACTIVATE As Long = &H10
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    Private Type tagMONITORINFO
       cbSize As Long
       rcMonitor As RECT
       rcWork As RECT
       dwFlags As Long
    End Type
     
    Private Declare Function GetMonitorInfo Lib "user32" _
                                            Alias "GetMonitorInfoA" ( _
                                            ByVal hMonitor As Long, _
                                            ByRef tMonInfo As tagMONITORINFO) As Long
    Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
     
    Private Declare Function EnumDisplayMonitors Lib "user32" (ByVal hdc As Long, ByRef lprcClip As Any, ByVal lpfnEnum As Long, dwData As MonitorData) As Long
     
    Private Declare Function SetWindowPos Lib "user32" _
                (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _
                 ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
     
    Private Type MonitorData
        MonitorForm As Access.Form
        MonitorNumber As Long
    End Type
     
    '--------------------------------------------------------------
    ' Position un formulaire sur un moniteur
    '--------------------------------------------------------------
    ' pForm : Formulaire à positionner
    ' pNumMoniteur : Numéro du moniteur
    '--------------------------------------------------------------
    Public Sub PosFormOnMonitor(pForm As Access.Form, Optional pNumMonitor As Long = 1)
        Dim ldata As MonitorData ' Données personnalisées pour énumération
        If GetSystemMetrics(SM_CMONITORS) > pNumMonitor Then Exit Sub
        Set ldata.MonitorForm = pForm
        ldata.MonitorNumber = pNumMonitor
        EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ldata
    End Sub
     
    ' Enumération des moniteurs
    Private Function MonitorEnumProc(ByVal hMonitor As Long, ByVal hdcMonitor As Long, lprcMonitor As RECT, dwData As MonitorData) As Long
    Dim lInfo As tagMONITORINFO
    dwData.MonitorNumber = dwData.MonitorNumber - 1
    If dwData.MonitorNumber = 0 Then
        ' Si moniteur demandé
        ' Initialise la structure
        lInfo.cbSize = Len(lInfo)
        ' Info du moniteur
        GetMonitorInfo hMonitor, lInfo
        ' Position le formulaire sur le moniteur
        SetWindowPos dwData.MonitorForm.hwnd, 0, lInfo.rcMonitor.Left, lInfo.rcMonitor.Top, 0, 0, SWP_NOSIZE
        ' Sélectionne le fomumaire
        DoCmd.SelectObject acForm, dwData.MonitorForm.Name
        ' Agrandit le formulaire
        DoCmd.Maximize
        ' Stoppe l'énumération
        MonitorEnumProc = 0
    Else
        ' Sinon, continue l'énumération
        MonitorEnumProc = 1
    End If
    End Function
    et la fonction a éxécuter sur un évènement (Form_Load) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Form_Load()
    PosFormOnMonitor Me, 2
    End Sub
    Jusqu'à présent je n'ai pas de problème au niveau des tests, l'application s'ouvre bien sur le 2ème écran. Là ou je bloque c'est au niveau de la position des formulaires. J'aimerai pouvoir décider exactement de leurs emplacement sur le 2ème écran. A l'heure actuelle j'utilise ce code pour les positionner :

    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
    Option Compare Database
    Option Explicit
     
    Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
     Dim Largeur As Integer, Hauteur As Integer
     
     
    ' Formulaires standard
    Sub FormPosition(F As Form)
      Largeur = GetSystemMetrics(0) 'obtenir la largeur de l'écran
      Hauteur = GetSystemMetrics(1) 'obtenir la longueur de l'écran
     
    If Largeur = 1024 And Hauteur = 768 Then 
            F.Move Left:=-110, Top:=-620 'je positionne les formulaires de cette facon uniquement si la résolution est de 1024x768
     Else
            Call Positionner(F) 'sinon j'apelle une fonction qui me centre automatiquement les formulaires.
    End If
    End Sub
    "Call Positionner(F)" ne peut s'appliquer pour une résolution de 1024X768. Cette fonction (disponible dans le FAQ) centre par rapport à la largeur et la hauteur de l'écran et dans cette résolution le bas de l'application est en partie caché par la barre des tâches c'est pourquoi je positionne les formulaires avec EXPRESSION.Move. Pour les autres résolutions je n'ai aucun problème.

    Ce que j'aimerais faire c'est pouvoir décider de la position de mes formulaires sur le 2ème écran. L'API SetWindowPos est ce qui positionne le form mais dans mon cas je ne sais pas comment je peux essayer d'appliquer mes conditions (Reste à savoir si c'est possible).

    Je viens donc demander vos conseils

    Merci de m'avoir lu

    Cordialement

    Guillaume

  2. #2
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    bjr,

    si tu souhaites un centrage (?), on peut récupérer la taille du formulaire en pixels avec GetWindowRect par exemple, puis utiliser je pense le rcWork du moniteur qui doit correspondre à la zone de travail (c-à-d sans la barre des tâches)
    un savant calcul permet de trouver la bonne position pour un centrage

    j'ai écris la suite sans avoir de 2è écran, c'est à tester et adapater si besoin :
    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
     
    Option Compare Database
    Option Explicit
     
    Private Const SM_CMONITORS As Long = 80&
    Private Const SWP_NOSIZE As Long = &H1
    Private Const SWP_NOACTIVATE As Long = &H10
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    Private Type tagMONITORINFO
       cbSize As Long
       rcMonitor As RECT
       rcWork As RECT
       dwFlags As Long
    End Type
     
    Private Declare Function GetMonitorInfo Lib "user32" _
                                            Alias "GetMonitorInfoA" ( _
                                            ByVal hMonitor As Long, _
                                            ByRef tMonInfo As tagMONITORINFO) As Long
    Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
     
    Private Declare Function EnumDisplayMonitors Lib "user32" (ByVal hdc As Long, ByRef lprcClip As Any, ByVal lpfnEnum As Long, dwData As MonitorData) As Long
     
    Private Declare Function SetWindowPos Lib "user32" _
                (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _
                 ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
     
    Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
     
    Private Type MonitorData
        MonitorForm As Access.Form
        MonitorNumber As Long
    End Type
     
    '--------------------------------------------------------------
    ' Position un formulaire sur un moniteur
    '--------------------------------------------------------------
    ' pForm : Formulaire à positionner
    ' pNumMoniteur : Numéro du moniteur
    '--------------------------------------------------------------
    Public Sub PosFormOnMonitor(pForm As Access.Form, Optional pNumMonitor As Long = 1)
        Dim ldata As MonitorData ' Données personnalisées pour énumération
        If GetSystemMetrics(SM_CMONITORS) > pNumMonitor Then Exit Sub
        Set ldata.MonitorForm = pForm
        ldata.MonitorNumber = pNumMonitor
        EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ldata
    End Sub
     
    ' Enumération des moniteurs
    Private Function MonitorEnumProc(ByVal hMonitor As Long, ByVal hdcMonitor As Long, lprcMonitor As RECT, dwData As MonitorData) As Long
    Dim lInfo As tagMONITORINFO
    Dim lFormRect As RECT
    dwData.MonitorNumber = dwData.MonitorNumber - 1
    If dwData.MonitorNumber = 0 Then
        ' Si moniteur demandé
        ' Initialise la structure
        lInfo.cbSize = Len(lInfo)
        ' Info du moniteur
        GetMonitorInfo hMonitor, lInfo
        ' Taille formulaire
        GetWindowRect dwData.MonitorForm.hwnd, lFormRect
        ' Position le formulaire sur le moniteur
        SetWindowPos dwData.MonitorForm.hwnd, 0, _
                           ((lInfo.rcWork.Right - lInfo.rcWork.Left + 1) - (lFormRect.Right - lFormRect.Left + 1)) / 2, _
                           ((lInfo.rcWork.Bottom - lInfo.rcWork.Top + 1) - (lFormRect.Bottom - lFormRect.Top + 1)) / 2, _
                           0, 0, SWP_NOSIZE
        ' Stoppe l'énumération
        MonitorEnumProc = 0
    Else
        ' Sinon, continue l'énumération
        MonitorEnumProc = 1
    End If
    End Function

  3. #3
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    230
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 230
    Points : 129
    Points
    129
    Par défaut
    Bonjour Arkham46

    Tout dabord merci pour ta réponse, je crois que tu étais le mieux placé pour le faire

    Je viens de tester ce que tu me propose. Tu as bien cerné mon besoin. Je souhaite en effet pouvoir centrer mes forms mais dans "l'espace de travail" donc sans la barre des taches. Ta proposition fonctionne très bien pour cela et je n'ai plus à me préocuper de choisir entre EXPRESSION.Move ou l'autre fonction.

    J'ai juste modifier le resultat final pour le top en rajoutant + 17. Les forms se collaient à la barre des taches. J'ai l'impression que GetWindowsRect prend en compte le bandeau même si il ne s'affiche pas. cela donne :

    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
    ' Enumération des moniteurs
    Private Function MonitorEnumProc(ByVal hMonitor As Long, ByVal hdcMonitor As Long, lprcMonitor As RECT, dwData As MonitorData) As Long
    Dim lInfo As tagMONITORINFO
    Dim lFormRect As RECT
    dwData.MonitorNumber = dwData.MonitorNumber - 1
    If dwData.MonitorNumber = 0 Then
        ' Si moniteur demandé
        ' Initialise la structure
        lInfo.cbSize = Len(lInfo)
        ' Info du moniteur
        GetMonitorInfo hMonitor, lInfo
        ' Taille formulaire
        GetWindowRect dwData.MonitorForm.hwnd, lFormRect
        ' Position le formulaire sur le moniteur
        SetWindowPos dwData.MonitorForm.hwnd, 0, _
                           ((lInfo.rcWork.Right - lInfo.rcWork.Left + 1) - (lFormRect.Right - lFormRect.Left + 1)) / 2, _
                           ((lInfo.rcWork.Bottom - (lInfo.rcWork.Top + 17) + 1) - (lFormRect.Bottom - lFormRect.Top + 1)) / 2, _
                           0, 0, SWP_NOSIZE
        ' Stoppe l'énumération
        MonitorEnumProc = 0
    Else
        ' Sinon, continue l'énumération
        MonitorEnumProc = 1
    End If
    End Function
    Ce premier test a été effectué avec PosFormOnMonitor Me, 1. Comme je le disais cela fonctionne bien sur mon poste qui ne possède qu'1 écran. J'ai donc par la suite essayé sur des postes ayant 2 moniteurs activés. Tout dabord avec PosFormOnMonitor Me, 1 puis la valeur 2

    Lorsque je test avec la valeur 1, les formulaires ne se centrent pas, c'est même le contraire ils sont complètement décalés. (les tests s'effectuent en 1024X768).
    Lorsque je test avec la valeur 2, les formulaires ne s'ouvrent pas sur le 2ème moniteur. Au niveau du positionnement, ils ont l'air de ce centrer en largeur mais pas en longueur. Le bas est en partie caché par la barre des tâches. Par contre cela n'a rien a voir avec le test en valeur 1 (décalage complet, en partie mordu par les coins droit et bas de l'écran.)

    Un autre test me fait constater que :

    Les formulaires se positionnent de la même facon avec 1 écran, PosFormOnMonitor Me, 2 et 2 écrans activés, PosFormOnMonitor Me, 1.

    Je précise que les utilisateurs de l'application sont pratiquement tous en résolution 1024x768. J'ai oublié l'idée de les amener vers une résolution plus grande. (les changements ne sont pas trop apprécié...). Mes formulaires sont donc adapté pour tenir dans "l'espace de travail" c'est à dire entre le haut du bureau et la barre des taches (petite marge de 5 pixel de chaque coté, ils ne collent donc pas complètement les bords Haut, droite, gauche et la barre des taches)

    J'avoue qu'à ce niveau je suis perdu et je manque sérieusement de compétence pour espérer trouver l'origine du problème.

    Merci en tout cas pour ton aide. J'apprécie énormément.

  4. #4
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    j'ai dû oublier le décalage du moniteur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        ' Position le formulaire sur le moniteur
        SetWindowPos dwData.MonitorForm.hwnd, 0, _
                          lInfo.rcMonitor.Left + ((lInfo.rcWork.Right - lInfo.rcWork.Left + 1) - (lFormRect.Right - lFormRect.Left + 1)) / 2, _
                          lInfo.rcMonitor.Top + ((lInfo.rcWork.Bottom - lInfo.rcWork.Top + 1) - (lFormRect.Bottom - lFormRect.Top + 1)) / 2, _
                           0, 0, SWP_NOSIZE
    essaye sinon de mettre un point d'arrêt et de t'aider en regardant (affichage => variables locales) ce qu'il se trouve dans lInfo.rcMonitor et lInfo.rcWork
    tu devrais retrouver les positions et tailles des moniteurs et y voir plus clair

  5. #5
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    230
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 230
    Points : 129
    Points
    129
    Par défaut
    Ca y est tout est résolu !

    Tes conseils ont été bénéfique ! J'ai mal étudié le comportement de la fonction et c'était logique que cela ne fonctionne pas.

    Voila ce que ça donne maintenant :

    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
    ' Enumération des moniteurs
    Private Function MonitorEnumProc(ByVal hMonitor As Long, ByVal hdcMonitor As Long, lprcMonitor As RECT, dwData As MonitorData) As Long
    Dim lInfo As tagMONITORINFO
    Dim lFormRect As RECT
    dwData.MonitorNumber = dwData.MonitorNumber
        ' Initialise la structure
        lInfo.cbSize = Len(lInfo)
        ' Info du moniteur
        GetMonitorInfo hMonitor, lInfo
        ' Taille formulaire
        GetWindowRect dwData.MonitorForm.hwnd, lFormRect
     
    If dwData.MonitorNumber = 1 Then
     
        ' Positionne le formulaire sur le 1er moniteur
        SetWindowPos dwData.MonitorForm.hwnd, 0, _
                          ((lInfo.rcWork.Right - lInfo.rcWork.Left + 1) - (lFormRect.Right - lFormRect.Left + 1)) / 2, _
                          ((lInfo.rcWork.Bottom - (lInfo.rcWork.Top + 17) + 1) - (lFormRect.Bottom - lFormRect.Top + 1)) / 2, _
                           0, 0, SWP_NOSIZE
    Else
     
        ' Positionne le formulaire sur le 2nd moniteur
        SetWindowPos dwData.MonitorForm.hwnd, 0, _
                          lInfo.rcMonitor.Right + ((lInfo.rcMonitor.Right - lInfo.rcMonitor.Left + 1) - (lFormRect.Right - lFormRect.Left + 1)) / 2, _
                          ((lInfo.rcMonitor.Bottom - (lInfo.rcMonitor.Top + 17) + 1) - (lFormRect.Bottom - lFormRect.Top + 1)) / 2, _
                           0, 0, SWP_NOSIZE
    End If
        ' Stoppe l'énumération
        MonitorEnumProc = 0
    End Function
    Merci beaucoup pour ton aide !!

    J'ai cependant 2 questions et peut être que tu auras une piste à me donner.

    Comment savoir si les 2 moniteurs sont activé avec l'API GetMonitorInfo?

    --> J'aimerais pouvoir proposer un formulaire avec choix (1er ou 2nd moniteur) si les 2 moniteurs sont activés sinon pas d'affichage du formulaire et donc forcément 1er moniteur par défaut.

    Il y a t-il possibilité d'avoir le rcmonitor du second écran ?

    --> Comme tu peux le voir dans la fonction je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     SetWindowPos dwData.MonitorForm.hwnd, 0, _
    lInfo.rcMonitor.Right + ((lInfo.rcMonitor.Right - lInfo.rcMonitor.Left + 1) - (lFormRect.Right - lFormRect.Left + 1)) / 2, _
    pour décaler le form vers le second moniteur (pour la resolution 1024x768, right = 1024). Si on imagine que la résolution du second écran est différente (+ grande) que celle du premier, lInfo.rcMonitor.Right + ne rajoutera que 1024 et non la largeur du second écran. Il faudrait donc un "autre" rcmonitor qui corresponde à la largeur du 2eme moniteur pour centrer le form. C'est du détail je sais, actuellement je n'ai pas ce problème mais dans l'éventualité que cela puisse se produire j'aimerais pouvoir le gérer.


  6. #6
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    d'abord pour l'écran activé ou non, je ne sais pas...

    sinon je crois que ça n'est pas bon...

    MonitorEnumProc est appelé pour chaque moniteur
    c'est pourquoi je décrémente dwData.MonitorNumber jusqu'à zéro
    si tu regardes bien l'exécution, tu verras que cette fonction est exécuté 2 fois si on demande le 2ème moniteur
    (et donc tu positionnes 2 fois ton formulaire)
    la première fois on décrémente dwData.MonitorNumber
    s'il tombe à zéro c'est qu'on a demandé le premier moniteur, sinon on continue et à l'exécution suivante on otient le positionnement du deuxième moniteur

    normalement tu n'a pas besoin de regarder le premier moniteur pour te positionner sur le second, le rcMonitor ou rcWork doit être correct pour chaque moniteur indépendamment de l'autre

    sinon on peut aussi regarder le lInfo.dwFlags qui doit valoir 1 pour le moniteur primaire et 0 pour le secondaire

  7. #7
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Citation Envoyé par Arkham46 Voir le message
    d'abord pour l'écran activé ou non, je ne sais pas...
    je précise : je ne sais pas déterminer si un écran est allumé ou éteint

    par contre on peut compter le nombre de moniteurs activés dans les paramètres d'affichage, même si ma méthode n'est pas des plus simple ça devrait marcher

    Ajouter la déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Private Declare Function EnumDisplayMonitorsCount Lib "user32" Alias "EnumDisplayMonitors" (ByVal hdc As Long, ByRef lprcClip As Any, ByVal lpfnEnum As Long, dwData As Long) As Long
    et ces fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Public Function CountMonitor() As Long
    Dim lCount As Long
    EnumDisplayMonitorsCount ByVal 0&, ByVal 0&, AddressOf MonitorEnumProcCount, lCount
    CountMonitor = lCount
    End Function
    Private Function MonitorEnumProcCount(ByVal hMonitor As Long, ByVal hdcMonitor As Long, lprcMonitor As RECT, dwData As Long) As Long
    dwData = dwData + 1
    MonitorEnumProcCount = 1
    End Function
    CountMonitor devrait renvoyer le nombre d'écrans du pc

  8. #8
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    230
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 230
    Points : 129
    Points
    129
    Par défaut
    Nickel pour la fonction CountMonitor() c'est exactement ce qu'il me faut. Encore une fois tu assures

    Par contre je ne suis pas certain de comprendre quand tu dis :

    sinon on continue et à l'exécution suivante on otient le positionnement du deuxième moniteur
    Lorsque j'ai regardé l'execution du code et que je mettais PosFormOnMonitor Me, 2, en effet il continuait pour aller executer :

    mais c'est la ou je ne comprend pas car lorsqu'il execute ceci, la fonction se ferme puis on retourne à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ldata
    je n'arrive pas a comprendre comment
    à l'exécution suivante on otient le positionnement du deuxième moniteur
    car la fonction se ferme et la ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SetWindowPos dwData.MonitorForm.hwnd, 0, _
                          lInfo.rcMonitor.Right + ((lInfo.rcMonitor.Right - lInfo.rcMonitor.Left + 1) - (lFormRect.Right - lFormRect.Left + 1)) / 2, _
                          ((lInfo.rcMonitor.Bottom - (lInfo.rcMonitor.Top + 17) + 1) - (lFormRect.Bottom - lFormRect.Top + 1)) / 2, _
                           0, 0, SWP_NOSIZE
    n'est pas executé pour le second moniteur. Je crois que il y a principe de fonctionnement que je ne pige pas dans tout ceci...
    Je vois ce que j'ai fais et en effet je ne fais que décaler le postionnement du formulaire situé sur le 1er moniteur...

  9. #9
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Je vais essayer d'être plus clair :
    - EnumDisplayMonitors exécute MonitorEnumProc pour chaque écran tant qu'on donne la valeur 1 au retour de cette fonction MonitorEnumProc
    - je passe une structure en paramètre qui contient le formulaire et le numéro de l'écran recherché
    - ce numéro est décrémenté à chaque passage dans la fonction MonitorEnumProc
    - s'il tombe à zéro on est arrivé à l'écran recherché et on obtient alors les informations de cet écran avec GetMonitorInfo

    on doit donc mettre MonitorEnumProc à 1 pour continuer l'énumération, et à 0 pour l'arrêter une fois qu'on est passé sur l'écran désiré

    si la fonction CountMonitor te renvoie bien 2 quand il y a 2 écrans, c'est que ça marche

    en débug pas à pas, je ne garantis pas qu'on voit l'enchaînement des fonctions
    en effet MonitorEnumProc redonne la main à EnumDisplayMonitors qui est une fonction externe, donc pas forcément étonnant qu'on ne revienne pas à MonitorEnumProc pour un deuxième passage, le déboggueur est un peu perturbé

    essaye de mettre un point d'arrêt ou un Stop directement dans le code de la fonction MonitorEnumProc, ça devrait y rentrer 2 fois lorsque nécessaire

    pour ce qui est des rcMonitor et rcWork

    pour 2 écrans de 1024*768 tu devrais avoir quelque chose du genre :

    => Ecran n°1
    rcMonitor.left = 0
    rcMonitor.top = 0
    rcMonitor.right = 1024
    rcMonitor.bottom = 768

    => Ecran n°2
    rcMonitor.left = 1024
    rcMonitor.top = 0
    rcMonitor.right = 2048
    rcMonitor.bottom = 768

    je crois que le pixel en haut à gauche est 0,0 , et celui en bas à droite est exclu
    l'écran n°1 va en fait de 0 à 1023 et de 0 à 767
    l'écran n°2 va de 1024 à 2047 et de 0 à 767

    la taille de l'écran est donc :
    rcMonitor.right - rcMonitor.left
    rcMonitor.bottom - rcMonitor.top
    (il ne faut pas retirer 1 comme je l'ai fait dans un code au-dessus)

    même chose pour rcWork mais sans la barre des tâches, par exemple :
    => Ecran n°1
    rcWork.left = 0
    rcWork.top = 0
    rcWork.right = 1024
    rcWork.bottom = 745

    => Ecran n°2
    rcWork.left = 1024
    rcWork.top = 0
    rcWork.right = 2048
    rcWork.bottom = 745

    voilà, bon courage

  10. #10
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    230
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 230
    Points : 129
    Points
    129
    Par défaut
    Merci beaucoup Arkham !!

    Je suis en train de mettre à jours mes post "non résolu" et je vois que je ne t'avais pas répondu !! Tout fonctionne parfaitement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2010] Ouvrir fenêtre modale sur le même écran que l'application
    Par jfchappuis dans le forum Access
    Réponses: 1
    Dernier message: 17/01/2014, 00h46
  2. Ouvrir une JFrame sur le second écran
    Par nassima_1418 dans le forum Agents de placement/Fenêtres
    Réponses: 9
    Dernier message: 22/10/2013, 11h31
  3. deplacer ou ouvrir une application sur le second moniteur
    Par enibris dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 20/12/2012, 22h59
  4. Réponses: 2
    Dernier message: 26/09/2008, 14h37
  5. Lien pour ouvrir une application sur pc
    Par debutantasp dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 12/01/2008, 13h55

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