Link to home
Start Free TrialLog in
Avatar of bkniazi
bkniazi

asked on

Change screen resolution from vb.net Application

Hi All,
I need to change the screen resolution from my vb.net application.
I have some code in vb.net which change the resolution but the task bar change its place
and go to middle of screen when the resolution is changed to 1024x768.
Any help on correcting the code or another example code will be appreciated.
The code is given below,
Add a module and add this code,
Option Strict Off
Option Explicit On
Module Module1
      
      Public Const EWX_LOGOFF As Short = 0
      Public Const EWX_SHUTDOWN As Short = 1
      Public Const EWX_REBOOT As Short = 2
      Public Const EWX_FORCE As Short = 4
      Public Const CCDEVICENAME As Short = 32
      Public Const CCFORMNAME As Short = 32
      Public Const DM_BITSPERPEL As Integer = &H40000
      Public Const DM_PELSWIDTH As Integer = &H80000
      Public Const DM_PELSHEIGHT As Integer = &H100000
      Public Const CDS_UPDATEREGISTRY As Short = &H1s
      Public Const CDS_TEST As Short = &H4s
      Public Const DISP_CHANGE_SUCCESSFUL As Short = 0
      Public Const DISP_CHANGE_RESTART As Short = 1
      
      Structure DEVMODE
            <VBFixedString(CCDEVICENAME),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=CCDEVICENAME)> Public dmDeviceName As String
            Dim dmSpecVersion As Short
            Dim dmDriverVersion As Short
            Dim dmSize As Short
            Dim dmDriverExtra As Short
            Dim dmFields As Integer
            Dim dmOrientation As Short
            Dim dmPaperSize As Short
            Dim dmPaperLength As Short
            Dim dmPaperWidth As Short
            Dim dmScale As Short
            Dim dmCopies As Short
            Dim dmDefaultSource As Short
            Dim dmPrintQuality As Short
            Dim dmColor As Short
            Dim dmDuplex As Short
            Dim dmYResolution As Short
            Dim dmTTOption As Short
            Dim dmCollate As Short
            <VBFixedString(CCFORMNAME),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=CCFORMNAME)> Public dmFormName As String
            Dim dmUnusedPadding As Short
            Dim dmBitsPerPel As Short
            Dim dmPelsWidth As Integer
            Dim dmPelsHeight As Integer
            Dim dmDisplayFlags As Integer
            Dim dmDisplayFrequency As Integer
      End Structure

    Declare Function EnumDisplaySettings Lib "user32" Alias "EnumDisplaySettingsA" (ByVal lpszDeviceName As Integer, ByVal iModeNum As Integer, ByRef lpDevMode As DEVMODE) As Boolean
    Declare Function ChangeDisplaySettings Lib "user32" Alias "ChangeDisplaySettingsA" (ByRef lpDevMode As DEVMODE, ByVal dwFlags As Integer) As Integer
    Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Integer, ByVal dwReserved As Integer) As Integer
End Module
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
And the form code is
Option Strict Off
Option Explicit On
Friend Class Form1
    Inherits System.Windows.Forms.Form
#Region "Windows Form Designer generated code "
    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()
    End Sub
    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal Disposing As Boolean)
        If Disposing Then
            If Not components Is Nothing Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(Disposing)
    End Sub
    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer
    Public ToolTip1 As System.Windows.Forms.ToolTip
    Public WithEvents _optRes_2 As System.Windows.Forms.RadioButton
    Public WithEvents _optRes_1 As System.Windows.Forms.RadioButton
    Public WithEvents _optRes_0 As System.Windows.Forms.RadioButton
    Public WithEvents cmdChange As System.Windows.Forms.Button
    Public WithEvents optRes As Microsoft.VisualBasic.Compatibility.VB6.RadioButtonArray
    Public WithEvents optShut As Microsoft.VisualBasic.Compatibility.VB6.RadioButtonArray
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.ToolTip1 = New System.Windows.Forms.ToolTip(Me.components)
        Me._optRes_2 = New System.Windows.Forms.RadioButton
        Me._optRes_1 = New System.Windows.Forms.RadioButton
        Me._optRes_0 = New System.Windows.Forms.RadioButton
        Me.cmdChange = New System.Windows.Forms.Button
        Me.optRes = New Microsoft.VisualBasic.Compatibility.VB6.RadioButtonArray(Me.components)
        Me.optShut = New Microsoft.VisualBasic.Compatibility.VB6.RadioButtonArray(Me.components)
        CType(Me.optRes, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.optShut, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        '_optRes_2
        '
        Me._optRes_2.BackColor = System.Drawing.SystemColors.Control
        Me._optRes_2.Cursor = System.Windows.Forms.Cursors.Default
        Me._optRes_2.Font = New System.Drawing.Font("Arial", 8.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me._optRes_2.ForeColor = System.Drawing.SystemColors.ControlText
        Me.optRes.SetIndex(Me._optRes_2, CType(2, Short))
        Me._optRes_2.Location = New System.Drawing.Point(53, 64)
        Me._optRes_2.Name = "_optRes_2"
        Me._optRes_2.RightToLeft = System.Windows.Forms.RightToLeft.No
        Me._optRes_2.Size = New System.Drawing.Size(81, 13)
        Me._optRes_2.TabIndex = 4
        Me._optRes_2.TabStop = True
        Me._optRes_2.Text = "1024 x 768"
        '
        '_optRes_1
        '
        Me._optRes_1.BackColor = System.Drawing.SystemColors.Control
        Me._optRes_1.Cursor = System.Windows.Forms.Cursors.Default
        Me._optRes_1.Font = New System.Drawing.Font("Arial", 8.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me._optRes_1.ForeColor = System.Drawing.SystemColors.ControlText
        Me.optRes.SetIndex(Me._optRes_1, CType(1, Short))
        Me._optRes_1.Location = New System.Drawing.Point(53, 40)
        Me._optRes_1.Name = "_optRes_1"
        Me._optRes_1.RightToLeft = System.Windows.Forms.RightToLeft.No
        Me._optRes_1.Size = New System.Drawing.Size(89, 13)
        Me._optRes_1.TabIndex = 3
        Me._optRes_1.TabStop = True
        Me._optRes_1.Text = "800 x 600"
        '
        '_optRes_0
        '
        Me._optRes_0.BackColor = System.Drawing.SystemColors.Control
        Me._optRes_0.Cursor = System.Windows.Forms.Cursors.Default
        Me._optRes_0.Font = New System.Drawing.Font("Arial", 8.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me._optRes_0.ForeColor = System.Drawing.SystemColors.ControlText
        Me.optRes.SetIndex(Me._optRes_0, CType(0, Short))
        Me._optRes_0.Location = New System.Drawing.Point(53, 16)
        Me._optRes_0.Name = "_optRes_0"
        Me._optRes_0.RightToLeft = System.Windows.Forms.RightToLeft.No
        Me._optRes_0.Size = New System.Drawing.Size(81, 13)
        Me._optRes_0.TabIndex = 2
        Me._optRes_0.TabStop = True
        Me._optRes_0.Text = "640 x 480"
        '
        'cmdChange
        '
        Me.cmdChange.BackColor = System.Drawing.SystemColors.Control
        Me.cmdChange.Cursor = System.Windows.Forms.Cursors.Default
        Me.cmdChange.Font = New System.Drawing.Font("Arial", 8.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.cmdChange.ForeColor = System.Drawing.SystemColors.ControlText
        Me.cmdChange.Location = New System.Drawing.Point(53, 87)
        Me.cmdChange.Name = "cmdChange"
        Me.cmdChange.RightToLeft = System.Windows.Forms.RightToLeft.No
        Me.cmdChange.Size = New System.Drawing.Size(113, 25)
        Me.cmdChange.TabIndex = 0
        Me.cmdChange.Text = "&Change Resolution"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.BackColor = System.Drawing.SystemColors.Control
        Me.ClientSize = New System.Drawing.Size(241, 125)
        Me.Controls.Add(Me._optRes_2)
        Me.Controls.Add(Me._optRes_1)
        Me.Controls.Add(Me._optRes_0)
        Me.Controls.Add(Me.cmdChange)
        Me.Cursor = System.Windows.Forms.Cursors.Default
        Me.Font = New System.Drawing.Font("Arial", 8.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
        Me.Location = New System.Drawing.Point(355, 151)
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.Name = "Form1"
        Me.RightToLeft = System.Windows.Forms.RightToLeft.No
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "Change the Screen Resolution"
        CType(Me.optRes, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.optShut, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
End Sub
#End Region
    Private Sub cmdChange_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdChange.Click
        Dim x As DEVMODE
        Dim y As Integer
        Dim z As Short

        y = EnumDisplaySettings(0, 0, x)
   With x
            .dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT
            If optRes(0).Checked Then
                .dmPelsWidth = 640
                .dmPelsHeight = 480
            ElseIf optRes(1).Checked Then
                .dmPelsWidth = 800
                .dmPelsHeight = 600
            Else
                .dmPelsWidth = 1024
                .dmPelsHeight = 768
            End If

        End With

        y = ChangeDisplaySettings(x, CDS_TEST)

        Select Case y
            Case DISP_CHANGE_RESTART
                z = MsgBox("You must restart your computer to apply these changes." & vbCrLf & vbCrLf & "Do you want to restart now?", MsgBoxStyle.YesNo + MsgBoxStyle.SystemModal, "Screen Resolution")
                If z = MsgBoxResult.Yes Then Call ExitWindowsEx(EWX_REBOOT, 0)
            Case DISP_CHANGE_SUCCESSFUL
                Call ChangeDisplaySettings(x, CDS_UPDATEREGISTRY)
                MsgBox("Screen resolution changed", MsgBoxStyle.Information, "Resolution Changed")
            Case Else
                MsgBox("Mode not supported", MsgBoxStyle.SystemModal, "Error")
        End Select
    End Sub
End Class
 
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

I took the code, and made it a little more modular, and tested it against some different resolutions and I don't see the problem with the taskbar (Windows 2000 SP4):

Public Class Screen

  Public Structure DeviceMode

    Private Const CCDEVICENAME As Short = 32
    Private Const CCFORMNAME As Short = 32

    <VBFixedString(CCDEVICENAME), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=CCDEVICENAME)> Public dmDeviceName As String
    Dim dmSpecVersion As Short
    Dim dmDriverVersion As Short
    Dim dmSize As Short
    Dim dmDriverExtra As Short
    Dim dmFields As Integer
    Dim dmOrientation As Short
    Dim dmPaperSize As Short
    Dim dmPaperLength As Short
    Dim dmPaperWidth As Short
    Dim dmScale As Short
    Dim dmCopies As Short
    Dim dmDefaultSource As Short
    Dim dmPrintQuality As Short
    Dim dmColor As Short
    Dim dmDuplex As Short
    Dim dmYResolution As Short
    Dim dmTTOption As Short
    Dim dmCollate As Short
    <VBFixedString(CCFORMNAME), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=CCFORMNAME)> Public dmFormName As String
    Dim dmUnusedPadding As Short
    Dim dmBitsPerPel As Short
    Dim dmPelsWidth As Integer
    Dim dmPelsHeight As Integer
    Dim dmDisplayFlags As Integer
    Dim dmDisplayFrequency As Integer
  End Structure 'DeviceMode'


  Private Declare Function EnumDisplaySettings _
    Lib "user32" Alias "EnumDisplaySettingsA" _
    (ByVal lpszDeviceName As Integer, ByVal iModeNum As Integer, _
     ByRef lpDevMode As DeviceMode) As Boolean

  Private Declare Function ChangeDisplaySettings _
    Lib "user32" Alias "ChangeDisplaySettingsA" _
    (ByRef lpDevMode As DeviceMode, ByVal dwFlags As Integer) _
    As Integer

  Private Declare Function ExitWindowsEx Lib "user32" _
    (ByVal uFlags As Integer, ByVal dwReserved As Integer) As Integer


  Public Shared Function ChangeResolution( _
    ByVal resWidth As Integer, ByVal resHeight As Integer) As Boolean

    Const CDS_TEST As Short = &H4
    Const CDS_UPDATEREGISTRY As Short = &H1
    Const DISP_CHANGE_SUCCESSFUL As Short = 0
    Const DISP_CHANGE_RESTART As Short = 1
    Const EWX_REBOOT As Short = 2

    ' Get all the available device modes.
    Dim deviceList As DeviceMode() = _
      EnumerateScreenModes()

    ' Assume the resolution settings are valid.
    Dim validResolution As Boolean = True

    ' Pick the corresponding resolution with the
    ' highest frequency.
    Dim selectedDevice As DeviceMode = _
      SelectResolution(deviceList, resWidth, resHeight)

    ' If there isn't a matching resolution for the
    ' desired width x height, then throw an
    ' exception.
    If selectedDevice.Equals(New DeviceMode) Then
      Throw New ArgumentException("Unsupported screen resolution:  " & _
        resWidth & " x " & resHeight)
    End If

    Dim restartMode As Integer = _
      ChangeDisplaySettings(selectedDevice, CDS_TEST)

    Select Case restartMode

      Case DISP_CHANGE_RESTART

        ' Ask to restart.
        Dim resultRestart As MsgBoxResult = _
          MsgBox("You must restart your computer to apply these changes." & vbCrLf & vbCrLf & "Do you want to restart now?", MsgBoxStyle.YesNo + MsgBoxStyle.SystemModal, "Screen Resolution")

        If resultRestart = MsgBoxResult.Yes Then
          ' Reboot the machine.
          ExitWindowsEx(EWX_REBOOT, 0)
        End If

      Case DISP_CHANGE_SUCCESSFUL

        ' Automatically change the resolution.
        Call ChangeDisplaySettings(selectedDevice, CDS_UPDATEREGISTRY)

      Case Else
        Throw New Exception("Mode not supported")

    End Select 'restartMode'

  End Function 'ChangeResolution'


  Public Shared Function EnumerateScreenModes() As DeviceMode()

    Const DM_DISPLAYFREQUENCY As Integer = &H400000
    Const DM_PELSWIDTH As Integer = &H80000
    Const DM_PELSHEIGHT As Integer = &H100000

    Dim deviceList As DeviceMode()
    Dim errorResult As Integer
    Dim countDevice As Integer = 0

    Do

      ' Call the enumerate function until no more
      ' settings are found.
      Dim deviceTest As DeviceMode

      errorResult = EnumDisplaySettings(0, countDevice, deviceTest)

      If errorResult <> 0 Then

        ReDim Preserve deviceList(countDevice)

        deviceList(countDevice) = deviceTest

        ' Set up the device to change the resolution
        ' and frequency.
        deviceList(countDevice).dmFields = DM_PELSWIDTH Or _
          DM_PELSHEIGHT Or DM_DISPLAYFREQUENCY

        ' Increment the counter.
        countDevice += 1
      End If

    Loop Until errorResult = 0

    Return deviceList

  End Function 'EnumerateScreenModes'


  Private Shared Function SelectResolution( _
    ByVal deviceList As DeviceMode(), ByVal resWidth As Integer, _
    ByVal resHeight As Integer) As DeviceMode

    ' Find the highest frequency for the
    ' desired screen dimensions.

    Dim maxFrequency As Integer = 0
    Dim selectDevice As DeviceMode = New DeviceMode

    ' Loop through each screen mode, and find the
    ' highest frequency.

    For Each currentDevice As DeviceMode In deviceList

      ' Only test modes where the screen dimensions
      ' match.

      If currentDevice.dmPelsWidth = resWidth And _
         currentDevice.dmPelsHeight = resHeight Then

        ' Test the current device mode to see if the
        ' frequency is the maximum.

        If currentDevice.dmDisplayFrequency > maxFrequency Then
          maxFrequency = currentDevice.dmDisplayFrequency

          selectDevice = currentDevice
        End If

      End If

    Next currentDevice

    Return selectDevice

  End Function 'SelectResolution'

End Class 'Screen'


Bob

Here is yet another version of the same thing...

    Private Const CCDEVICENAME = 32
    Private Const CCFORMNAME = 32
    Private Const DM_PELSWIDTH = &H80000
    Private Const DM_PELSHEIGHT = &H100000

    'typedef struct _devicemode {
    '  BCHAR  dmDeviceName[CCHDEVICENAME];
    '  WORD   dmSpecVersion;
    '  WORD   dmDriverVersion;
    '  WORD   dmSize;
    '  WORD   dmDriverExtra;
    '  DWORD  dmFields;
    '  union {
    '    struct {
    '      short dmOrientation;
    '      short dmPaperSize;
    '      short dmPaperLength;
    '      short dmPaperWidth;
    '      short dmScale;
    '      short dmCopies;
    '      short dmDefaultSource;
    '      short dmPrintQuality;
    '    };
    '    POINTL dmPosition;
    '    DWORD  dmDisplayOrientation;
    '    DWORD  dmDisplayFixedOutput;
    '  };
    '  short  dmColor;
    '  short  dmDuplex;
    '  short  dmYResolution;
    '  short  dmTTOption;
    '  short  dmCollate;
    '  BYTE  dmFormName[CCHFORMNAME];
    '  WORD  dmLogPixels;
    '  DWORD  dmBitsPerPel;
    '  DWORD  dmPelsWidth;
    '  DWORD  dmPelsHeight;
    '  union {
    '    DWORD  dmDisplayFlags;
    '    DWORD  dmNup;
    '  }
    '  DWORD  dmDisplayFrequency;
    '#if(WINVER >= 0x0400)
    '  DWORD  dmICMMethod;
    '  DWORD  dmICMIntent;
    '  DWORD  dmMediaType;
    '  DWORD  dmDitherType;
    '  DWORD  dmReserved1;
    '  DWORD  dmReserved2;
    '#if (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400)
    '  DWORD  dmPanningWidth;
    '  DWORD  dmPanningHeight;
    '#End If
    '#endif /* WINVER >= 0x0400 */
    '} DEVMODE;

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=4)> _
    Private Structure DEVMODE
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=CCDEVICENAME)> Dim dmDeviceName As String
        Dim dmSpecVersion As Short
        Dim dmDriverVersion As Short
        Dim dmSize As Short
        Dim dmDriverExtra As Short
        Dim dmFields As Integer
        Dim dmOrientation As Short
        Dim dmPaperSize As Short
        Dim dmPaperLength As Short
        Dim dmPaperWidth As Short
        Dim dmScale As Short
        Dim dmCopies As Short
        Dim dmDefaultSource As Short
        Dim dmPrintQuality As Short
        Dim dmColor As Short
        Dim dmDuplex As Short
        Dim dmYResolution As Short
        Dim dmTTOption As Short
        Dim dmCollate As Short
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=CCFORMNAME)> Dim dmFormName As String
        Dim dmUnusedPadding As Short
        Dim dmBitsPerPel As Short
        Dim dmPelsWidth As Integer
        Dim dmPelsHeight As Integer
        Dim dmDisplayFlags As Integer
        Dim dmDisplayFrequency As Integer
    End Structure

    'BOOL EnumDisplaySettings(
    '  LPCTSTR lpszDeviceName,  // display device
    '  DWORD iModeNum,          // graphics mode
    '  LPDEVMODE lpDevMode      // graphics mode settings
    ');
    Private Declare Ansi Function EnumDisplaySettings Lib "user32" _
        Alias "EnumDisplaySettingsA" _
        (ByVal lpszDeviceName As Integer, _
        ByVal iModeNum As Integer, _
        ByRef lpDevMode As DEVMODE) As Boolean

    'LONG ChangeDisplaySettings(
    '  LPDEVMODE lpDevMode,  // graphics mode
    '  DWORD dwflags         // graphics mode options
    ');
    Private Declare Ansi Function ChangeDisplaySettings Lib "user32" _
        Alias "ChangeDisplaySettingsA" _
        (ByRef lpDevMode As DEVMODE, _
        ByVal dwflags As Integer) As Integer

    Private Sub ChangeRes(ByVal iWidth As Integer, ByVal iHeight As Integer, Optional ByVal iColorDepth As Integer = 0)
        Dim blnWorked As Boolean
        Dim i As Integer
        Dim DevM As DEVMODE

        i = 0
        Do
            blnWorked = EnumDisplaySettings(0, i, DevM)
            If blnWorked Then
                If DevM.dmPelsWidth = iWidth And DevM.dmPelsHeight = iHeight Then
                    Debug.WriteLine(DevM.dmBitsPerPel)
                    If iColorDepth > 0 Then
                        DevM.dmBitsPerPel = iColorDepth
                    End If
                    ChangeDisplaySettings(DevM, 0)
                    Exit Sub
                End If
            End If
            i = i + 1
        Loop Until (blnWorked = False)
    End Sub
Avatar of bkniazi
bkniazi

ASKER

Hi TheLearnedOne
Sorry for giving a late comment,I have checked your class code it working nice for changing resolution from 800x600
to 1024x768, but when we change resolution from 1024x768 to 800x600 then the task bar hides from the screen
Same problem occur in changing to 640x480.I have also windows 2000 and Sp4 like you.
Please check it ,Thanks
Avatar of bkniazi

ASKER

Hi graye,
Thanks for replying to my question I have used your example Module but the taskbar hides when we change
the resolution to 800x600.Please work on this problem area.Many thanks.................................................
In my code, this is the line that causes problems:

ChangeDisplaySettings(selectedDevice, CDS_TEST)

If you comment this line out, then it works fine changing from 1024 x 768 to 800 x 600.  I don't know why this messes things up.

Bob
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bkniazi

ASKER

Hi TheLearnedOne,
Many thanks for solving the problem in my code.You have answered in a best way
A lot of thanks again..................