Précédent   Forum des professionnels en informatique > Logiciels > Microsoft Office > Access > VBA Access
VBA Access Le forum pour les questions relatives au code VBA sous Access, et à son environnement de développement VBE.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/06/2011, 14h37   #1
Membre régulier
 
Inscription : juillet 2010
Messages : 230
Détails du profil
Informations forums :
Inscription : juillet 2010
Messages : 230
Points : 82
Points : 82
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 :
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 :
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 :
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
Chagui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 21h17   #2
Responsable Access
 
Avatar de Arkham46
 
Inscription : septembre 2003
Messages : 4 300
Détails du profil
Informations personnelles :
Localisation : France, Loiret (Centre)

Informations forums :
Inscription : septembre 2003
Messages : 4 300
Points : 7 939
Points : 7 939
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 :
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
__________________
Assistant de création/modification de rubans Office
Utilisez en VBA les librairies graphiques GDI, GDI+ et openGL

Blog Office Mon Site DVP
Arkham46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 11h12   #3
Membre régulier
 
Inscription : juillet 2010
Messages : 230
Détails du profil
Informations forums :
Inscription : juillet 2010
Messages : 230
Points : 82
Points : 82
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 :
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.
Chagui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 11h38   #4
Responsable Access
 
Avatar de Arkham46
 
Inscription : septembre 2003
Messages : 4 300
Détails du profil
Informations personnelles :
Localisation : France, Loiret (Centre)

Informations forums :
Inscription : septembre 2003
Messages : 4 300
Points : 7 939
Points : 7 939
j'ai dû oublier le décalage du moniteur :

Code :
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
__________________
Assistant de création/modification de rubans Office
Utilisez en VBA les librairies graphiques GDI, GDI+ et openGL

Blog Office Mon Site DVP
Arkham46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 14h00   #5
Membre régulier
 
Inscription : juillet 2010
Messages : 230
Détails du profil
Informations forums :
Inscription : juillet 2010
Messages : 230
Points : 82
Points : 82
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 :
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 :
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.

Chagui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 15h12   #6
Responsable Access
 
Avatar de Arkham46
 
Inscription : septembre 2003
Messages : 4 300
Détails du profil
Informations personnelles :
Localisation : France, Loiret (Centre)

Informations forums :
Inscription : septembre 2003
Messages : 4 300
Points : 7 939
Points : 7 939
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
__________________
Assistant de création/modification de rubans Office
Utilisez en VBA les librairies graphiques GDI, GDI+ et openGL

Blog Office Mon Site DVP
Arkham46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 15h23   #7
Responsable Access
 
Avatar de Arkham46
 
Inscription : septembre 2003
Messages : 4 300
Détails du profil
Informations personnelles :
Localisation : France, Loiret (Centre)

Informations forums :
Inscription : septembre 2003
Messages : 4 300
Points : 7 939
Points : 7 939
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 :
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 :
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
__________________
Assistant de création/modification de rubans Office
Utilisez en VBA les librairies graphiques GDI, GDI+ et openGL

Blog Office Mon Site DVP
Arkham46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 15h37   #8
Membre régulier
 
Inscription : juillet 2010
Messages : 230
Détails du profil
Informations forums :
Inscription : juillet 2010
Messages : 230
Points : 82
Points : 82
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 :

Citation:
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 :
EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ldata
je n'arrive pas a comprendre comment
Citation:
à l'exécution suivante on otient le positionnement du deuxième moniteur
car la fonction se ferme et la ligne :

Code :
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...
Chagui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 16h04   #9
Responsable Access
 
Avatar de Arkham46
 
Inscription : septembre 2003
Messages : 4 300
Détails du profil
Informations personnelles :
Localisation : France, Loiret (Centre)

Informations forums :
Inscription : septembre 2003
Messages : 4 300
Points : 7 939
Points : 7 939
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
__________________
Assistant de création/modification de rubans Office
Utilisez en VBA les librairies graphiques GDI, GDI+ et openGL

Blog Office Mon Site DVP
Arkham46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2011, 10h07   #10
Membre régulier
 
Inscription : juillet 2010
Messages : 230
Détails du profil
Informations forums :
Inscription : juillet 2010
Messages : 230
Points : 82
Points : 82
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.
Chagui est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h01.


 
 
 
 
Partenaires

Hébergement Web