Modifier l'écran d'affichage principal (PrimaryDisplay)

Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 - Modifié par Jayme65 le 19/01/2016 à 11:57
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 - 19 janv. 2016 à 17:18
Bonjour,

Je cherche à pouvoir modifier l'écran d'affichage principal...malheureusement sans succès jusqu'à présent!
Voilà le code que j'ai, pourriez-vous svp m'aider à voir où ça coince!
(Il n'y a pas d'erreur de compilation)
D'avance merci pour l'aide que vous voudrez bien m'accorder !

Imports System.Runtime.InteropServices
Class MainWindow
    Const CCDEVICENAME As Short = 32
    Const CCFORMNAME As Short = 32
 
    Private Const MONITORINFOF_PRIMARY As Integer = &H1
    Private Const DISPLAY_DEVICE_ATTACHED_TO_DESKTOP As Integer = &H1
    Private Const DISPLAY_DEVICE_PRIMARY_DEVICE As Integer = &H4
    Private Const DISPLAY_DEVICE_MIRRORING_DRIVER As Integer = &H8
    Private Const DISPLAY_DEVICE_VGA_COMPATIBLE As Integer = &H10
    Private Const DISPLAY_DEVICE_REMOVABLE As Integer = &H20
    Private Const DISPLAY_DEVICE_MODESPRUNED As Integer = &H8000000
 
    Private Const DM_POSITION = &H20
    Private Const DM_DISPLAYORIENTATION = &H80 ' XP only
    Private Const DM_BITSPERPEL = &H40000
    Private Const DM_PELSWIDTH = &H80000
    Private Const DM_PELSHEIGHT = &H100000
    Private Const DM_DISPLAYFLAGS = &H200000
    Private Const DM_DISPLAYFREQUENCY = &H400000
    'Private Const DM_DISPLAYFIXEDOUTPUT As Long = &H20000000 ' XP only
 
    Private Const ENUM_CURRENT_SETTINGS As Integer = -1
    Private Const ENUM_REGISTRY_SETTINGS As Integer = -2
    Private Const EDS_RAWMODE As Integer = &H2
 
    Private Const CDS_UPDATEREGISTRY As Integer = &H1
    Private Const CDS_TEST As Integer = &H2
    Private Const CDS_FULLSCREEN As Integer = &H4
    Private Const CDS_GLOBAL As Integer = &H8
    Private Const CDS_SET_PRIMARY As Integer = &H10
    Private Const CDS_VIDEOPARAMETERS As Integer = &H20
    Private Const CDS_NORESET As Integer = &H10000000
    Private Const CDS_RESET As Integer = &H40000000
    Private Const CDS_FORCE As Integer = &H80000000
    Private Const CDS_NONE As Integer = 0
 
    Public Structure PointL
        Dim x As Integer
        Dim y As Integer
    End Structure
 
    <Flags()> _
    Enum DisplayDeviceStateFlags As Integer
        AttachedToDesktop = &H1
        MultiDriver = &H2
        PrimaryDevice = &H4
        MirroringDriver = &H8
        VGACompatible = &H10
        Removable = &H20
        ModesPruned = &H8000000
        Remote = &H4000000
        Disconnect = &H2000000
    End Enum
 
    '0 is Not Attached
 
    Const DISPLAY_PRIMARY_DEVICE = &H4 'Primary device
 
    'Holds the information of display adpter
    Private Structure DISPLAY_DEVICE
        Public cb As Integer
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCDEVICENAME)> Public DeviceName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> Public DeviceString As String
        Public StateFlags As Short
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> Public DeviceID As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> Public DeviceKey As String
    End Structure
 
    'Holds the setting of display adapter
    Private Structure DEVMODE
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCDEVICENAME)> _
        Public dmDeviceName As String
        Public dmSpecVersion As Short
        Public dmDriverVersion As Short
        Public dmSize As Short
        Public dmDriverExtra As Short
        Public dmFields As Integer
        Public dmOrientation As Short
        'Public dmPaperSize As Short
        'Public dmPaperLength As Short
        'Public dmPaperWidth As Short
        'Public dmScale As Short
        Public dmPositionX As Integer
        Public dmPositionY As Integer
        Public dmCopies As Short
        Public dmDefaultSource As Short
        Public dmPrintQuality As Short
        Public dmColor As Short
        Public dmDuplex As Short
        Public dmYResolution As Short
        Public dmTTOption As Short
        Public dmCollate As Short
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCFORMNAME)> _
        Public dmFormName As String
        Public dmLogPixels As Short
        Public dmBitsPerPel As Short
        Public dmPelsWidth As Integer
        Public dmPelsHeight As Integer
        Public dmDisplayFlags As Integer
        Public dmDisplayFrequency As Integer
        Public dmICMMethod As Integer
        Public dmICMIntent As Integer
        Public dmMediaType As Integer
        Public dmDitherType As Integer
        Public dmReserved1 As Integer
        Public dmReserved2 As Integer
        Public dmPanningWidth As Integer
        Public dmPanningHeight As Integer
        'Public dmPosition As Point
        'Public dmPositionX As Integer
        'Public dmPositionY As Integer
    End Structure
 
    'API declaration set or get display adpter information
    <DllImport("user32.dll")> _
    Private Shared Function EnumDisplayDevices(ByVal Unused As Integer, _
    ByVal iDevNum As Short, ByRef lpDisplayDevice As DISPLAY_DEVICE, ByVal dwFlags As Integer) As Integer
    End Function
 
    <DllImport("user32.dll")> _
    Private Shared Function EnumDisplaySettings(ByVal lpszDeviceName As String, _
    ByVal iModeNum As Integer, ByRef lpDevMode As DEVMODE) As Integer
    End Function
 
    <DllImport("user32.dll")> _
    Private Shared Function ChangeDisplaySettingsEx(ByVal lpszDeviceName As String, _
    ByRef lpDevMode As DEVMODE, ByVal hWnd As Integer, ByVal dwFlags As Integer, _
    ByVal lParam As Integer) As Integer
    End Function
    <DllImport("user32.dll")> _
    Private Shared Function ChangeDisplaySettingsEx(ByVal lpszDeviceName As String, _
    ByRef lpDevMode As IntPtr, ByVal hWnd As Integer, ByVal dwFlags As Integer, _
    ByVal lParam As Integer) As Integer
    End Function
 
Public Sub SetAsPrimaryMonitor(id As UInteger)
        Dim device = New DISPLAY_DEVICE()
        Dim deviceMode = New DEVMODE()
        device.cb = Marshal.SizeOf(device)
 
        EnumDisplayDevices(Nothing, id, device, 0)
        EnumDisplaySettings(device.DeviceName, -1, deviceMode)
        Dim offsetx = deviceMode.dmPositionX
        Dim offsety = deviceMode.dmPositionY
        deviceMode.dmPositionX = 0
        deviceMode.dmPositionY = 0
 
        ChangeDisplaySettingsEx(device.DeviceName, deviceMode, 0, (CDS_SET_PRIMARY Or CDS_UPDATEREGISTRY Or CDS_NORESET), 0)
 
        device = New DISPLAY_DEVICE()
        device.cb = Marshal.SizeOf(device)
 
        ' Update remaining devices
        Dim otherid As UInteger = 0
        While EnumDisplayDevices(Nothing, otherid, device, 0)
 
            If device.StateFlags = DisplayDeviceStateFlags.AttachedToDesktop AndAlso otherid <> id Then
                device.cb = Marshal.SizeOf(device)
                Dim otherDeviceMode = New DEVMODE()
 
                EnumDisplaySettings(device.DeviceName, -1, otherDeviceMode)
 
                otherDeviceMode.dmPositionX -= offsetx
                otherDeviceMode.dmPositionY -= offsety
 
                ChangeDisplaySettingsEx(device.DeviceName, otherDeviceMode, 0, (CDS_UPDATEREGISTRY Or CDS_NORESET), 0)
            End If
 
            device.cb = Marshal.SizeOf(device)
            otherid += 1
        End While
 
        ' Apply settings
        ChangeDisplaySettingsEx(Nothing, 0, 0, CDS_NONE, 0)
    End Sub
 
    Private Sub Button1_Click_1(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
        SetAsPrimaryMonitor(0)
    End Sub
End Class

7 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
19 janv. 2016 à 12:29
Bonjour,
1) tu as ouvert cette discussioçn dans le forum général de Visual Basic, qui comprend plusieurs sous-forums, chacun d'eux correspondant à un langage différent de développement.
Nous ne savons donc pas avec certitude sous QUOI tu développes !
2) qu'entends-tu exactement par : "modifier l'écran d'affichage principal" ???.
En d'autres termes :! qu'attends-tu très exactement de l'exécution de ta procédure SetAsPrimaryMonitor ?
Il sera à ce propos bien que tu en commentes chacune des lignes de code, juste pour nous permettre de voir ce que tu penses être le résultat de ces lignes.
0
Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 2
Modifié par Jayme65 le 19/01/2016 à 12:38
ucfoutu,

Merci pour ta réponse et ta demande de précision qui devrait en effet me permettre d'être mieux aider!

1. Désolé, je n'ai pas fais assez attention...c'est bien une question qui devrait se trouver dans la partie "VB.NET" !

2. Par 'modifier l'écran d'affichage principal' j'entends: dans une configuration multi-écran, pouvoir modifier quel sera l'écran principal (au niveau du système donc)
Comme on le ferait dans Panneau de configuration > Affichage > Résolution d’écran
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
19 janv. 2016 à 12:50
bonjour à vous deux !
J'ai redirigé vers la section VB net !
A ma connaissance ChangeDisplaySetting permet de modifier les paramètres de l'écran principal mais pas de changer d'écran principal !
Je fouille sur le Net pour avoir des infos plus précises
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
19 janv. 2016 à 13:28
Inspire toi de ce code trouvé dans cette discussion : http://codes-sources.commentcamarche.net/forum/affich-1631661-choisir-l-ecran-d-affichage
Une feuille et 2 boutons ! Le second bouton est actif uniquement si 2 écrans
quand tu cliques sur un bouton l'affichage bascule sur l'écran correspondant !
Je ne peux pas tester car je n'ai qu'un écran

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Button2.Enabled = False
        'pour connaitre le nombre d'écrans connectés
        Dim nbre_écran As Integer
        nbre_écran = Screen.AllScreens.LongLength
        Label1.Text "Nombre d'écrans " & nbre_écran.ToString
        Dim écran As Screen = Screen.PrimaryScreen
        Label2.Text = "WorkingArea écran 1: " & Chr(13) & écran.WorkingArea.ToString
        If nbre_écran > 1 Then
            Label3.Text = "WorkingArea écran 2: " & Chr(13) & Screen.AllScreens(1).WorkingArea.ToString
            Button2.Enabled = True
        End If
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Me.Location = New System.Drawing.Point(Screen.PrimaryScreen.WorkingArea.Location.X + 100, Screen.PrimaryScreen.WorkingArea.Location.Y + 100)
    End Sub

    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        Me.Location = New System.Drawing.Point(Screen.AllScreens(1).WorkingArea.Location.X + 100, Screen.AllScreens(1).WorkingArea.Location.Y + 100)
    End Sub)

0
Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 2
19 janv. 2016 à 13:32
vb95,
Merci pour ta réponse...et pour le code posté!

Je dois cependant te préciser qu'il ne s'agit pas ici de déplacer une fenêtre sur un autre écran...mais de modifier l'affichage principal au niveau du système! (Tout comme on le ferait dans Panneau de configuration > Affichage > Résolution d’écran)
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
19 janv. 2016 à 14:00
somme toute tu veux changer d'écran mais pas spécialement pour le programme VB que tu fais mais pour tout le système !
Là je sèche ! désolé
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
19 janv. 2016 à 14:25
A essayer ! Sans certitude

Private Sub Button1_Click_1(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
        SetAsPrimaryMonitor(0)
    End Sub


rajoute un Bouton2 avec ce code
Private Sub Button2_Click_1(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
        SetAsPrimaryMonitor(1)
    End Sub


bouton1 active l'écran 0 et bouton2 l'écran1 ( sous toutes réserves )
0
Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 2 > vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024
19 janv. 2016 à 14:44
Merci..mais tu penses bien que j'avais testé le code avec ces 2 appels (c'est d'ailleurs compris dans le code)...malheureusement cela coince encore quelque part...et pourtant j'ai le sentiment d'être très prés ;-)
Merci pour toute aide supplémentaire!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
19 janv. 2016 à 14:17
Je m'en doutais un peu ...
Que vient alors faire là-dedans l'utilisation de ChangeDisplaySetting ? Rien ... Cette fonction permet de modifier les paramètres de configuration d'un écran spécifié, non d'en faire l'écran principal ou autre ...
Un sujet identique a été discuté il y a peu :
http://codes-sources.commentcamarche.net/forum/affich-10059173-manipuler-les-objets-screen
Lis mon dernier message dans cette discussion.

Une telle "opération", qui ne saurait être "occasionnelle", n'a aucune raison, d'être effectuée en mode exécution d'une application. Elle doit être rare et donc faire l'objet d'une décision manuelle. .
0
Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 2
Modifié par Jayme65 le 19/01/2016 à 14:41
> Cette fonction permet de modifier les paramètres de configuration d'un écran spécifié, non d'en faire l'écran principal ou autre
Et si! (https://msdn.microsoft.com/en-us/library/windows/desktop/dd183413%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396), regarde à 'CDS_SET_PRIMARY'

> Une telle "opération", qui ne saurait être "occasionnelle", n'a aucune raison, d'être effectuée en mode exécution d'une application
Et si! C'est même la solution retenue par Steam (dans le mode 'Big Picture') pour lancer toute application (la plupart ne permettant pas de fixer un écran externe comme écran de démarrage)...sur un écran 'externe'
Par contre je suis d'accord avec toi...en cas de plantage, si on n'y prend garde, on risquerait de ne pouvoir rétablir la configuration initiale
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 19/01/2016 à 17:36
Ce n'est pas aussi simple que tend à l'exposer le lien auquel tu te réfères.
Les choses peuvent différer d'une machine à l'autre et dépendent de la nature des matériels (pour dialoguer avec Windows).
Je crois avoir en outre lu qu'il fallait d'abord, avec cette fonction, repositionner l'écran choisi pour devenir le primaire.
Je sais qu'un outil ad hoc a été conçu pour faire face à tous les cas de figure. Son nom est Ultramon. Il permet de faire certaines choses, dont celle-ci, assez facilement.
Je maintiens ce que j'ai dit plus haut en matière de modifications apportées à la configuration d'une machine. Rien à dire si uniquement sur la tienne, mais reprochable si ton appli est distribuée ailleurs.
(je n'accepte par exemple personnellement aucune appli modifiant mes configurations. Si la "chose" est de surcroît faite "en silence", sans que le vendeur ne m'en ait averti, je sors carrément de mes gonds ...)

EDIT si la chose était si simple, Microsoft n'aurait eu aucune raison de limiter en lecture seule la propriété Primary de la classe Screen.
S'il ne l'a pas rendue également possible en écriture, c'est très probablement parce que que les implications, différences, configurations, etc ... à gérer étaient bien trop nombreuses, d'une part et que, d'autre part, il ne voulait pas supporter la responsabilité des conséquences éventuelles (notamment en cas d'interruption brutale) de modifications de la configuration.
________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
0
Rejoignez-nous