65.9K
CodeProject 正在变化。 阅读更多。
Home

.NET ChangeDisplaySettingsEX 封装

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.86/5 (3投票s)

2009年7月6日

CPOL

2分钟阅读

viewsIcon

52108

downloadIcon

3167

ChangeDisplaySettingsEx

Display Settings Tester

引言

在编写一个程序,以便快速更改我的显示设置时,我发现 .NET 环境中没有很多可用的示例,而且没有一个示例展示了更改分辨率和主显示器以及连接和断开监视器的完整画面。

UpdateSettings 函数能够设置主显示器、连接和断开监视器,以及设置显示属性 SizeBitsPerPixelFrequency

背景

我经常根据正在进行的操作更改双显示器电脑的显示设置。例如,当我使用 Visual Studio 时,我喜欢将两个监视器都设置为 1280x1024,但当我浏览网页时,我会将它们设置为 1024x768。然后还有那些使用屏幕边缘来滚动世界的模拟/冒险游戏。如果您连接了第二个监视器,这些游戏将无法正常运行。因此,需要更改另一个显示设置以断开第二个监视器。

Using the Code

Display_Settings 可以添加到任何窗体。它包含允许您为其提供组合框、面板和滑块以填充和控制的属性。这意味着您只需要在“应用”按钮上调用 UpdateSettings 。所有控件属性均经过处理,以确保不应用任何不正确的设置。Display_Settings 还提供允许您控制自己的控件的事件。

Private Sub btnApply_Click(ByVal sender As System.Object, _
	ByVal e As System.EventArgs) Handles btnApply.Click
    Me.Display_Settings1.UpdateSettings()
End Sub    

UpdateSettings 函数还允许您通过传递 Display_Settings.Display 类的数组来更新存储的设置。Display_Settings.Display 类是可序列化的,并继承自 Kim MajorContractBase(of T) 类。这使得序列化变得容易。非常感谢 Kim Major 提供的这个类。

UpdateSettings 函数首先通过将当前主显示器从位置 0,0 移开并将新的主显示器移动到位置 0,0 来设置主显示器。

然后它循环遍历每个显示设备。如果显示器要断开,它会将它移动到位置 0,0 并将其大小设置为 0,0。如果显示器连接,它将将其设置为其新设置。这也有连接先前未连接的任何显示器的效果。

最后,我们再次循环遍历所有显示设备并应用设置。

UpdateSettings 函数

Public Function UpdateSettings(ByVal Displays As Display()) _
	As WinAPI.DisplaySetting_Results
        If Not Me.PrimaryDisplayID = Me.PrimaryDisplayRegistryID Then
            SetPrimaryDisplay(Me.m_Displays(Me.PrimaryDisplayRegistryID).DeviceName, _
            	Me.m_Displays(Me.PrimaryDisplayID).DeviceName)
        End If
        For Each disp As Display In Displays
            If Not disp.Attached Then
                Dim dm As New WinAPI.DEVMODE
                dm.dmDeviceName = New [String](New Char(31) {})
                dm.dmFormName = New [String](New Char(31) {})
                dm.dmSize = CShort(Marshal.SizeOf(dm))
                dm.dmFields = WinAPI.DEVMODE_Flags.DM_POSITION Or _
                	WinAPI.DEVMODE_Flags.DM_PELSWIDTH Or WinAPI.DEVMODE_Flags.DM_PELSHEIGHT
                dm.dmPelsWidth = 0
                dm.dmPelsHeight = 0
                dm.dmPosition.x = 0
                dm.dmPosition.y = 0
                Dim Result As WinAPI.DisplaySetting_Results = _
		WinAPI.ChangeDisplaySettingsEx_
                	(disp.DeviceName, dm, Nothing, WinAPI.DeviceFlags.CDS_UPDATEREGISTRY _
                	Or WinAPI.DeviceFlags.CDS_NORESET, 0)
            Else
                Dim dm As New WinAPI.DEVMODE
                dm.dmDeviceName = New [String](New Char(31) {})
                dm.dmFormName = New [String](New Char(31) {})
                dm.dmSize = CShort(Marshal.SizeOf(dm))
                dm.dmFields = WinAPI.DEVMODE_Flags.DM_POSITION Or _
                	WinAPI.DEVMODE_Flags.DM_PELSWIDTH Or _
		WinAPI.DEVMODE_Flags.DM_PELSHEIGHT _
                	Or WinAPI.DEVMODE_Flags.DM_DISPLAYFLAGS _
                	Or WinAPI.DEVMODE_Flags.DM_BITSPERPEL _
                	Or WinAPI.DEVMODE_Flags.DM_DISPLAYFREQUENCY
                dm.dmPelsWidth = disp.Size.Width
                dm.dmPelsHeight = disp.Size.Height
                dm.dmPosition.x = disp.Location.X
                dm.dmPosition.y = disp.Location.Y
                dm.dmBitsPerPel = disp.BitsPerPixel
                dm.dmDisplayFrequency = disp.Frequency
                Dim Result As WinAPI.DisplaySetting_Results = _
                	WinAPI.ChangeDisplaySettingsEx(disp.DeviceName, dm, _
                	Nothing, WinAPI.DeviceFlags.CDS_SET_PRIMARY _
                	Or WinAPI.DeviceFlags.CDS_UPDATEREGISTRY _
                	Or WinAPI.DeviceFlags.CDS_NORESET, 0)

            End If
        Next
        For i As Integer = Displays.Length - 1 To 0 Step -1
            Dim dm1 As New WinAPI.DEVMODE
            dm1.dmDeviceName = New [String](New Char(31) {})
            dm1.dmFormName = New [String](New Char(31) {})
            dm1.dmSize = CShort(Marshal.SizeOf(dm1))
            Dim lStatus As WinAPI.DisplaySetting_Results = _
            	WinAPI.ChangeDisplaySettingsEx(Me.m_Displays(i).DeviceName, _
            		dm1, Nothing, WinAPI.DeviceFlags.CDS_UPDATEREGISTRY, Nothing)
            WinAPI.OutputDebugString(lStatus.ToString & vbCrLf)
        Next
        Me.InitializeDisplays()
    End Function  

SetPrimaryDisplay 函数

Public Sub SetPrimaryDisplay_
	(ByVal OldPrimary As String, ByVal NewPrimary As String)
        Dim Result As WinAPI.DisplaySetting_Results = 0

        Dim dm1 As WinAPI.DEVMODE = NewDevMode()
        WinAPI.EnumDisplaySettings(NewPrimary, _
		WinAPI.DEVMODE_SETTINGS.ENUM_REGISTRY_SETTINGS, dm1)
        Dim dm3 As WinAPI.DEVMODE = NewDevMode()
        dm3.dmFields = WinAPI.DEVMODE_Flags.DM_POSITION
        dm3.dmPosition.x = dm1.dmPelsWidth
        dm3.dmPosition.y = 0
        Result = WinAPI.ChangeDisplaySettingsEx(OldPrimary, dm3, _
        	Nothing, WinAPI.DeviceFlags.CDS_UPDATEREGISTRY _
		Or WinAPI.DeviceFlags.CDS_NORESET, 0)
        Console.WriteLine(Result.ToString)

        Dim dm2 As WinAPI.DEVMODE = NewDevMode()
        WinAPI.EnumDisplaySettings(NewPrimary, _
		WinAPI.DEVMODE_SETTINGS.ENUM_REGISTRY_SETTINGS, dm2)
        Dim dm4 As WinAPI.DEVMODE = NewDevMode()
        dm4.dmFields = WinAPI.DEVMODE_Flags.DM_POSITION
        dm4.dmPosition.x = 0
        dm4.dmPosition.y = 0
        Result = WinAPI.ChangeDisplaySettingsEx(NewPrimary, dm4, Nothing, _
        	WinAPI.DeviceFlags.CDS_SET_PRIMARY Or WinAPI.DeviceFlags.CDS_UPDATEREGISTRY _
        	Or WinAPI.DeviceFlags.CDS_NORESET, 0)
        Console.WriteLine(Result.ToString)

        Dim dm5 As WinAPI.DEVMODE = NewDevMode()
        Result = WinAPI.ChangeDisplaySettingsEx(OldPrimary, dm5, _
        	Nothing, WinAPI.DeviceFlags.CDS_UPDATEREGISTRY, Nothing)
        Console.WriteLine(Result.ToString)
        Dim dm6 As WinAPI.DEVMODE = NewDevMode()
        Result = WinAPI.ChangeDisplaySettingsEx(NewPrimary, dm6, Nothing, _
        	WinAPI.DeviceFlags.CDS_SET_PRIMARY Or WinAPI.DeviceFlags.CDS_UPDATEREGISTRY, 0)
        Console.WriteLine(Result.ToString)

        Console.WriteLine(Result.ToString)
    End Sub

关注点

务必确保您的显示器具有共同的边缘。如果屏幕重叠或存在间隙,您可能会遇到一些奇怪的效果,例如鼠标指针没有指向鼠标位置。我不得不使用键盘几次来重置我的显示设置。

ChangeDisplaySettingsEX 建议要应用设置,您应该使用 ChangeDisplaySettingsEX(nothing, nothing, nothing, 0, nothing)。这对我不起作用。我必须为每个设备名称调用 ChangeDisplaySettingsEX ,并使用一个空的 DEVMODE 结构和标志 CDS_UPDATEREGISTRY

历史

  • 2009 年 7 月 6 日:第一个版本
© . All rights reserved.