Solved

Change Display Resolutions

Posted on 2002-07-04
13
300 Views
Last Modified: 2008-02-01
I found a script from http://www.mvps.org/vbnet/index.html?code/enums/enumdisplaychange.htm and this enough me change the pc display resolutions. But now got a problem, this just can work in Win9x, i try in Win2k or WinXP will got error, how to fix it, please help. Thanks

-== Module ==-
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2002 VBnet, Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you can not publish
'               or reproduce this code on any web site,
'               on any online service, or distribute on
'               any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Declare Function EnumDisplaySettings Lib "user32" _
    Alias "EnumDisplaySettingsA" _
   (ByVal lpszDeviceName As Long, _
    ByVal iModeNum As Long, _
    lpDevMode As Any) As Boolean
         
Public Declare Function GetDeviceCaps Lib "gdi32" _
   (ByVal hdc As Long, _
    ByVal nIndex As Long) As Long

Public Declare Function ChangeDisplaySettings Lib "user32" _
    Alias "ChangeDisplaySettingsA" _
   (lpDevMode As Any, _
    ByVal dwflags As Long) As Long
         
Public Declare Function SetMenuDefaultItem Lib "user32" _
   (ByVal hMenu As Long, _
    ByVal uItem As Long, _
    ByVal fByPos As Long) As Long
 
Public Declare Function GetMenu Lib "user32" _
   (ByVal hWnd As Long) As Long
   
Public Declare Function GetSubMenu Lib "user32" _
   (ByVal hMenu As Long, _
   ByVal nPos As Long) As Long
         
Public Const LOGPIXELSX As Long = 88
Public Const LOGPIXELSY As Long = 90
Public Const BITSPIXEL As Long = 12
Public Const HORZRES As Long = 8
Public Const VERTRES As Long = 10

Public Const CCDEVICENAME As Long = 32
Public Const CCFORMNAME As Long = 32

Public Const DM_GRAYSCALE As Long = &H1
Public Const DM_INTERLACED As Long = &H2

Public Const DM_BITSPERPEL As Long = &H40000
Public Const DM_PELSWIDTH As Long = &H80000
Public Const DM_PELSHEIGHT As Long = &H100000
Public Const DM_DISPLAYFLAGS As Long = &H200000

Public Const CDS_UPDATEREGISTRY As Long = &H1
Public Const CDS_TEST As Long = &H2
Public Const CDS_FULLSCREEN As Long = &H4
Public Const CDS_GLOBAL As Long = &H8
Public Const CDS_SET_PRIMARY As Long = &H10
Public Const CDS_NORESET As Long = &H10000000
Public Const CDS_SETRECT As Long = &H20000000
Public Const CDS_RESET As Long = &H40000000
Public Const CDS_FORCE As Long = &H80000000

'Return values for ChangeDisplaySettings
'Public Const DISP_CHANGE_SUCCESSFUL = 0
'Public Const DISP_CHANGE_RESTART = 1
'Public Const DISP_CHANGE_FAILED = -1
'Public Const DISP_CHANGE_BADMODE = -2
'Public Const DISP_CHANGE_NOTUPDATED = -3
'Public Const DISP_CHANGE_BADFLAGS = -4
'Public Const DISP_CHANGE_BADPARAM = -5

Public Type DEVMODE
   dmDeviceName      As String * CCDEVICENAME
   dmSpecVersion     As Integer
   dmDriverVersion   As Integer
   dmSize            As Integer
   dmDriverExtra     As Integer
   dmFields          As Long
   dmOrientation     As Integer
   dmPaperSize       As Integer
   dmPaperLength     As Integer
   dmPaperWidth      As Integer
   dmScale           As Integer
   dmCopies          As Integer
   dmDefaultSource   As Integer
   dmPrintQuality    As Integer
   dmColor           As Integer
   dmDuplex          As Integer
   dmYResolution     As Integer
   dmTTOption        As Integer
   dmCollate         As Integer
   dmFormName        As String * CCFORMNAME
   dmUnusedPadding   As Integer
   dmBitsPerPel      As Integer
   dmPelsWidth       As Long
   dmPelsHeight      As Long
   dmDisplayFlags    As Long
   dmDisplayFrequency As Long
End Type


-==Form==-
Option Explicit

'vars set in load
Dim currHRes As Long
Dim currVRes As Long
Dim currBPP As Long

'var set in mnuModes
Dim currMenuItem As Long

'array of valid resolutions & colour depths
Dim resArray() As Long
   
'const for the members of the array
'i.e. resArray(resWidth, Index) = 1024
'i.e. resArray(resHeight, Index) = 768
'i.e. resArray(resDepth, Index)= 16  'Bits per pixel
Const resWidth = 1
Const resHeight = 2
Const resDepth = 3


Private Sub Form_Load()

  'retrieves the current screen resolution for
  'later comparison against DEVMODE values in
  'CompareSettings.
   currHRes = GetDeviceCaps(hdc, HORZRES)
   currVRes = GetDeviceCaps(hdc, VERTRES)
   currBPP = GetDeviceCaps(hdc, BITSPIXEL)
   
   Dim maxItems As Long
   InitializeDisplayMenu maxItems
   FinalizeDisplayMenu maxItems
   
End Sub


Private Sub FinalizeDisplayMenu(maxItems As Long)

  'This adds a separator and a final menu item,
  'providing the ability to open the control panel
  'display settings page from the app.
   If maxItems > 0 Then
   
      Dim hMenu As Long
      Dim r As Long
     
     'add the separator
      maxItems = maxItems + 1
      Load mnuModes(maxItems)
      mnuModes(maxItems).Caption = "-"
     
     'add the final item
      maxItems = maxItems + 1
      Load mnuModes(maxItems)
      mnuModes(maxItems).Caption = "Show Display Settings"
     
     'finally, bold the newly-added menuitem
      hMenu = GetSubMenu(GetMenu(Me.hWnd), 0)
      Call SetMenuDefaultItem(hMenu, maxItems - 1, True)
   
   End If
       
End Sub


Private Sub InitializeDisplayMenu(maxItems As Long)

   Dim DM As DEVMODE
   Dim dMode As Long
   
  '36 should be enough to hold your settings.
  'It's trimmed back at the end of this routine.
   ReDim resArray(1 To 3, 0 To 35)
   
  'set the DEVMODE flags and structure size
   DM.dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT Or DM_BITSPERPEL
   DM.dmSize = LenB(DM)
   
  'The first mode is 0
   dMode = 0
     
  'call the API to retrieve the values for the
  'specified dMode
   Do While EnumDisplaySettings(0&, dMode, DM) > 0
   
     'if the BitsPerPixel is greater than 4
     '(16 colours), then add the item to a menu
      If DM.dmBitsPerPel >= 4 Then
         Call MenuAdd(DM, resArray(), maxItems)
      End If
     
     'increment and call again. Continue until
     'EnumDisplaySettings returns 0 (no more settings)
      dMode = dMode + 1
   
   Loop
   
  'trim back the resArray to fit the number of actual entries.
   ReDim Preserve resArray(1 To 3, 0 To maxItems)
   
End Sub


Private Function CompareSettings(DM As DEVMODE) As Long
   
  'compares the current screen resolution with
  'the current DEVMODE values.   Returns TRUE if
  'the horizontal and vertical resolutions, and
  'the bits per pixel colour depth, are the same.
   CompareSettings = (DM.dmBitsPerPel = currBPP) And _
                      DM.dmPelsHeight = currVRes And _
                      DM.dmPelsWidth = currHRes
   
End Function


Private Sub MenuAdd(DM As DEVMODE, resArray() As Long, mnuCount As Long)
 
   Dim mType As String
   
  'used to determine when the colour depth has
  'changed, so we can add a separator to the menu.
   Static lastBitsPerPel As Long
   
  'select the appropriate text string based on
  'the colour depth
   Select Case DM.dmBitsPerPel
      Case 4:      mType = "16 Color"
      Case 8:      mType = "256 Color"
      Case 16:     mType = "High Color"
      Case 24, 32: mType = "True Color"
   End Select

  'if this is the first item, we can't load the menu
  'array item, and it will not require a separator.
   If mnuCount > 0 Then
   
     'load a new menu item to the array
      Load mnuModes(mnuCount)
   
     'determine if the colour depth has changed. If so,
     'make the caption a separator, and load a new item
     'to hold the item.
      If lastBitsPerPel <> DM.dmBitsPerPel Then
     
         mnuModes(mnuCount).Caption = "-"
         mnuCount = mnuCount + 1
         Load mnuModes(mnuCount)
     
      End If
   End If
   
  'create the menu caption
   mnuModes(mnuCount).Caption = DM.dmPelsWidth & "x" & _
                                DM.dmPelsHeight & "  [" & _
                                DM.dmBitsPerPel & " bit " & _
                                mType & "]"
   
  'see if this is the current resolution,
  'and if so, check the menu item
   mnuModes(mnuCount).Checked = CompareSettings(DM)
   If mnuModes(mnuCount).Checked Then currMenuItem = mnuCount
   
   resArray(resWidth, mnuCount) = DM.dmPelsWidth
   resArray(resHeight, mnuCount) = DM.dmPelsHeight
   resArray(resDepth, mnuCount) = DM.dmBitsPerPel
   
  'save the current DEVMODE value for depth
  'and increment the menu item count, ready for
  'the next call
   lastBitsPerPel = DM.dmBitsPerPel
   mnuCount = mnuCount + 1
   
End Sub


Private Sub Command1_Click()

   Dim maxItems As Long
   
   InitializeDisplayMenu maxItems
   Command1.Enabled = False
   
   FinalizeDisplayMenu maxItems
   
End Sub


Private Sub mnuModes_Click(Index As Integer)

   Dim DM As DEVMODE
   
   Select Case Index
   
      Case mnuModes.Count
     
        'show the display control panel
         Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3", 1)
     
      Case Else
       
        'change the current resolution, no prompting
        'BE CAREFUL .. you could set your system to a
        'setting which renders the display difficult to read.
       
         With DM
         
            .dmPelsWidth = resArray(resWidth, Index)
            .dmPelsHeight = resArray(resHeight, Index)
            .dmBitsPerPel = resArray(resDepth, Index)
            .dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT Or DM_BITSPERPEL
            .dmSize = LenB(DM)
         End With
         
         If ChangeDisplaySettings(DM, CDS_FORCE) <> 0 Then
         
             MsgBox "Error! Perhaps your hardware is not up to the task?"
             
         End If
         
        'indicate the current menu selection
         mnuModes(currMenuItem).Checked = False
         mnuModes(Index).Checked = True
         currMenuItem = Index
   
   End Select

End Sub
0
Comment
Question by:it31
13 Comments
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 7129525
In the API function declare, try replacing the ending A by W: EnumDisplaySettingsA -> EnumDisplaySettingsW

Now, what is your problem/error exactly?
0
 

Author Comment

by:it31
ID: 7129538
angellll,

Try in Win2k Server

got this error:
Run-Time Error "91";
Object variable or With Block variable not set.
0
 

Author Comment

by:it31
ID: 7129546
Sorry is Win2k Professional.

Try in Win98 is nothing problem.

And if i am use A the error is:

run-time error '9'
subscript out of range...

0
 

Author Comment

by:it31
ID: 7129558
try to add in use back the A
and add in On Error Resume Next in the

Private Sub MenuAdd(DM As DEVMODE, resArray() As Long, mnuCount As Long)
 
   Dim mType As String
>>   On Error Resume Next

It is no error happen, but the resolution will Duplicate.
0
 
LVL 3

Expert Comment

by:carruina
ID: 7130163
I test it but I have only a problem with resArray

Change this line
ReDim resArray(1 To 3, 0 To 35) -> ReDim resArray(1 To 3, 0 To 1000)

But there is something wrong in the code because you repeat the resolutons four times.
0
 
LVL 5

Expert Comment

by:jayeshshah
ID: 7130455
Public Const EWX_LOGOFF = 0
Public Const EWX_SHUTDOWN = 1
Public Const EWX_REBOOT = 2
Public Const EWX_FORCE = 4
Public Const CCDEVICENAME = 32
Public Const CCFORMNAME = 32
Public Const DM_BITSPERPEL = &H40000
Public Const DM_PELSWIDTH = &H80000
Public Const DM_PELSHEIGHT = &H100000
Public Const CDS_UPDATEREGISTRY = &H1
Public Const CDS_TEST = &H4
Public Const DISP_CHANGE_SUCCESSFUL = 0
Public Const DISP_CHANGE_RESTART = 1

Type typDevMODE
    dmDeviceName       As String * CCDEVICENAME
    dmSpecVersion      As Integer
    dmDriverVersion    As Integer
    dmSize             As Integer
    dmDriverExtra      As Integer
    dmFields           As Long
    dmOrientation      As Integer
    dmPaperSize        As Integer
    dmPaperLength      As Integer
    dmPaperWidth       As Integer
    dmScale            As Integer
    dmCopies           As Integer
    dmDefaultSource    As Integer
    dmPrintQuality     As Integer
    dmColor            As Integer
    dmDuplex           As Integer
    dmYResolution      As Integer
    dmTTOption         As Integer
    dmCollate          As Integer
    dmFormName         As String * CCFORMNAME
    dmUnusedPadding    As Integer
    dmBitsPerPel       As Integer
    dmPelsWidth        As Long
    dmPelsHeight       As Long
    dmDisplayFlags     As Long
    dmDisplayFrequency As Long
End Type

Declare Function EnumDisplaySettings Lib "user32" Alias "EnumDisplaySettingsA" (ByVal lpszDeviceName As Long, ByVal iModeNum As Long, lptypDevMode As Any) As Boolean
Declare Function ChangeDisplaySettings Lib "user32" Alias "ChangeDisplaySettingsA" (lptypDevMode As Any, ByVal dwFlags As Long) As Long
Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long


Dim typDevM As typDevMODE
Dim lngResult As Long
Dim intAns    As Integer

' Retrieve info about the current graphics mode
' on the current display device.
lngResult = EnumDisplaySettings(0, 0, typDevM)

' Set the new resolution. Don't change the color
' depth so a restart is not necessary.
With typDevM
    .dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT
    .dmPelsWidth = 640  'ScreenWidth (640,800,1024, etc)
    .dmPelsHeight = 480 'ScreenHeight (480,600,768, etc)
End With

' Change the display settings to the specified graphics mode.
lngResult = ChangeDisplaySettings(typDevM, CDS_TEST)
Select Case lngResult
    Case DISP_CHANGE_RESTART
        intAns = MsgBox("You must restart your computer to apply these changes." & _
            vbCrLf & vbCrLf & "Do you want to restart now?", _
            vbYesNo + vbSystemModal, "Screen Resolution")
        If intAns = vbYes Then Call ExitWindowsEx(EWX_REBOOT, 0)
    Case DISP_CHANGE_SUCCESSFUL
        Call ChangeDisplaySettings(typDevM, CDS_UPDATEREGISTRY)
        MsgBox "Screen resolution changed", vbInformation, "Resolution Changed"
    Case Else
        MsgBox "Mode not supported", vbSystemModal, "Error"
End Select
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:it31
ID: 7130933
jayeshshah,

Please dont locked the question.
0
 

Author Comment

by:it31
ID: 7130941
carruina,

Yes you are correct, i donno why it will repeat, so how to fix it? i believe this the the WinAPI problem? Any ideas to all?
0
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 7131300
0
 

Author Comment

by:it31
ID: 7131388
ryancys,

These one is same with why i post to here i belive. And you have any sample code can work in WinXP as well?

Thanks
0
 
LVL 3

Accepted Solution

by:
carruina earned 100 total points
ID: 7131391
No, There is not any problem with the API
The shows all the graphic modes, and the the diferent refesh frecuency also.


Change in the Function MenuAdd this line to show the different Dsiplay Frecuency.

'create the menu caption
  mnuModes(mnuCount).Caption = DM.dmPelsWidth & "x" & _
                               DM.dmPelsHeight & "  [" & _
                               DM.dmBitsPerPel & " bit " & _
                               mType & " ]" & DM.dmDisplayFrequency & " hz"


0
 

Author Comment

by:it31
ID: 7131495
carruina,

Got 1 more problem, when i change the site, the window no will auto refresh all the screen, i can see taskbar in the top.

How to fix it?
0
 

Author Comment

by:it31
ID: 7131641
If ChangeDisplaySettings(DM, CDS_FORCE) <> 0 Then

Change to:

If ChangeDisplaySettings(DM, 1) <> 0 Then

Then will refresh the backgroup screen.

Thanks!
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now