AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Change Display Mode
Goto page 1, 2  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
shimanov



Joined: 25 Sep 2005
Posts: 610

PostPosted: Tue Feb 28, 2006 8:43 am    Post subject: Change Display Mode Reply with quote

Change the primary display mode parameters, including: resolution, color quality, and refresh rate.

The required API functions are available with all versions of Windows.

Code:
system_path = %A_WinDir%\system
if ( A_OSType != WIN32_WINDOWS )
   system_path = %system_path%32
   
id_image_list := IL_Create( 1, 0, 0 )
IL_Add( id_image_list, system_path "\shell32.dll", 131 )

Gui, Add, ListView, x5 y5 w280 h200 grid gChangeDisplayMode, |width|height|quality (bits)|frequency (Hz)
Gui, Show, x50 y50 w290 h210, Change Display Mode

LV_SetImageList( id_image_list, 1 )

Gui, +LastFound

struct_devicemode_size = 156
VarSetCapacity( device_mode, struct_devicemode_size, 0 )

EncodeInteger( struct_devicemode_size, 2, &device_mode, 36 )

; ENUM_CURRENT_SETTINGS
success := DllCall( "EnumDisplaySettings", "uint", 0, "uint", -1, "uint", &device_mode )

current?width := DecodeInteger( "uint4", &device_mode, 108, false )
current?height := DecodeInteger( "uint4", &device_mode, 112, false )
current?quality := DecodeInteger( "uint4", &device_mode, 104, false )
current?frequency := DecodeInteger( "uint4", &device_mode, 120, false )

loop,
{
   success := DllCall( "EnumDisplaySettings", "uint", 0, "uint", A_Index-1, "uint", &device_mode )
   if ( ErrorLevel or !success )
      break
      
   mode?width := DecodeInteger( "uint4", &device_mode, 108, false )
   mode?height := DecodeInteger( "uint4", &device_mode, 112, false )
   mode?quality := DecodeInteger( "uint4", &device_mode, 104, false )
   mode?frequency := DecodeInteger( "uint4", &device_mode, 120, false )
   
   if ( mode?width = current?width
         and mode?height = current?height
         and mode?quality = current?quality
         and mode?frequency = current?frequency )
      options = Focus Icon1 Select
   else
      options = Icon0
   
   LV_Add( options, "", mode?width, mode?height, mode?quality, mode?frequency )
}

loop, 5
   LV_ModifyCol( A_Index, "AutoHdr Integer" )

LV_ModifyCol( 2, "Sort" )

current?index := LV_GetNext()

; LVM_ENSUREVISIBLE
SendMessage, 0x1000+19, current?index-1, false, SysListView321
return

GuiClose:
ExitApp

ChangeDisplayMode:
   if ( A_GuiEvent != "DoubleClick" )
      return

   ; DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY
   EncodeInteger( 0x00040000|0x00080000|0x00100000|0x00400000, 4, &device_mode, 40 )
   
   LV_GetText( value, A_EventInfo, 4 )
      EncodeInteger( value, 4, &device_mode, 104 )
   LV_GetText( value, A_EventInfo, 2 )
      EncodeInteger( value, 4, &device_mode, 108 )
   LV_GetText( value, A_EventInfo, 3 )
      EncodeInteger( value, 4, &device_mode, 112 )
   LV_GetText( value, A_EventInfo, 5 )
      EncodeInteger( value, 4, &device_mode, 120 )

   ; 0 = change mode dynamically
   ; 2 = test if mode is valid
   ; 1 = 0+update user profile in registry
   result := DllCall( "ChangeDisplaySettings", "uint", &device_mode, "uint", 0 )
   if ( ErrorLevel )
      MsgBox, [ChangeDisplaySettings] failure: EL = %ErrorLevel%
   else
   {
      if ( result = 0 )
      {
         LV_Modify( current?index, "Icon0" )
         current?index := A_EventInfo
            LV_Modify( current?index, "Icon1" )
      
         result = DISP_CHANGE_SUCCESSFUL
      }
      else if ( result = 1 )
         result = DISP_CHANGE_RESTART
      else if ( result = -1 )
         result = DISP_CHANGE_FAILED
      else if ( result = -2 )
         result = DISP_CHANGE_BADMODE
      else if ( result = -3 )
         result = DISP_CHANGE_NOTUPDATED
      else if ( result = -4 )
         result = DISP_CHANGE_BADFLAGS
      else if ( result = -5 )
         result = DISP_CHANGE_BADPARAM
      else if ( result = -6 )
         result = DISP_CHANGE_BADDUALVIEW
      
      MsgBox, 0, Change Display Mode, %result%, 2
   }
return

DecodeInteger( p_type, p_address, p_offset, p_hex=true )
{
   old_FormatInteger := A_FormatInteger

   if ( p_hex )
      SetFormat, Integer, hex
   else
      SetFormat, Integer, dec

   sign := InStr( p_type, "u", false )^1

   StringRight, size, p_type, 1

   loop, %size%
      value += ( *( ( p_address+p_offset )+( A_Index-1 ) ) << ( 8*( A_Index-1 ) ) )

   if ( sign and size <= 4 and *( p_address+p_offset+( size-1 ) ) & 0x80 )
      value := -( ( ~value+1 ) & ( ( 2**( 8*size ) )-1 ) )

   SetFormat, Integer, %old_FormatInteger%

   return, value
}

EncodeInteger( p_value, p_size, p_address, p_offset )
{
   loop, %p_size%
      DllCall( "RtlFillMemory"
         , "uint", p_address+p_offset+A_Index-1
         , "uint", 1
         , "uchar", ( p_value >> ( 8*( A_Index-1 ) ) ) & 0xFF )
}


Last edited by shimanov on Thu Mar 02, 2006 5:16 pm; edited 2 times in total
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10666

PostPosted: Wed Mar 01, 2006 12:26 am    Post subject: Reply with quote

Very useful. Given the number of requests over the past two years, I know this is going to be a popular one!
Back to top
View user's profile Send private message Send e-mail
shimanov



Joined: 25 Sep 2005
Posts: 610

PostPosted: Wed Mar 01, 2006 1:25 am    Post subject: Reply with quote

One more example of AHk's immediate usefulness, in its current form, and with its current function. All in all, a very capable development platform.
Back to top
View user's profile Send private message
Guest






PostPosted: Thu Mar 02, 2006 3:05 pm    Post subject: Reply with quote

shimanov wrote:
One more example of AHk's immediate usefulness


I need that and thanks you.
Bat cant understand what is command for fix resolution
Example 1200x1024
Back to top
shimanov



Joined: 25 Sep 2005
Posts: 610

PostPosted: Thu Mar 02, 2006 5:21 pm    Post subject: Reply with quote

Anonymous wrote:
I need that and thanks you.


Sure.

Quote:
Bat cant understand what is command for fix resolution
Example 1200x1024


You will need all four parameters to specify a video mode. Check for valid modes with the original script.

Code:
struct_devicemode_size = 156
VarSetCapacity( device_mode, 156, 0 )

EncodeInteger( struct_devicemode_size, 2, &device_mode, 36 )

success := DllCall( "EnumDisplaySettings", "uint", 0, "uint", -1, "uint", &device_mode )

; DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY
EncodeInteger( 0x00040000|0x00080000|0x00100000|0x00400000, 4, &device_mode, 40 )

EncodeInteger( 32, 4, &device_mode, 104 )                              ; quality (i.e., color depth)
EncodeInteger( 1600, 4, &device_mode, 108 )                              ; width
EncodeInteger( 1200, 4, &device_mode, 112 )                              ; height
EncodeInteger( 60, 4, &device_mode, 120 )                              ; frequency (i.e., refresh rate)

DllCall( "ChangeDisplaySettings", "uint", &device_mode, "uint", 0 )
Back to top
View user's profile Send private message
Invalid User



Joined: 14 Feb 2005
Posts: 440
Location: Texas, Usa

PostPosted: Fri Mar 03, 2006 11:42 am    Post subject: Reply with quote

This is great work! I want to add this to the function lib I have as a sticky, but as I attempted to lose the gui part, I broke it miserably. Will you please create a fucntion to change the disp settings that will allow changes on multi monitor systems and also add error levels for attempts to apply settings that cannot be handled such as too high res attempted to be set.

Thanks very much, keep up the great work.
_________________
my lame sig Smile
Back to top
View user's profile Send private message Send e-mail Yahoo Messenger
Guest






PostPosted: Mon Mar 06, 2006 10:39 am    Post subject: Reply with quote

@shimanov
I steel not understand what is what parameters
do you writed code what is work whit 1200x124,32,60Hz?
thanks
Back to top
PhiLho



Joined: 27 Dec 2005
Posts: 6787
Location: France (near Paris)

PostPosted: Mon Mar 06, 2006 11:14 am    Post subject: Reply with quote

You were lost by the code at start, missing the helpful comments at the end:
Quote:
EncodeInteger( 32, 4, &device_mode, 104 ) ; quality (i.e., color depth)
EncodeInteger( 1600, 4, &device_mode, 108 ) ; width
EncodeInteger( 1200, 4, &device_mode, 112 ) ; height
EncodeInteger( 60, 4, &device_mode, 120 ) ; frequency (i.e., refresh rate)

You can use the code given by shimanov as is, changing only the first parameter of these function calls: replace 1600 by 1200 (or 1280?), 1200 by 1024 (not 124 I suppose...) and you are done.
Oh well, to restructure a bit this code (untested):
Code:
; ChangeDisplaySettings.ahk
; by shimanov
; http://www.autohotkey.com/forum/viewtopic.php?t=8355

colorDepth = 32 ; bits (quality)
screenWidth = 1600 ; pixels
screenHeight = 1200 ; pixels
refreshRate = 60 ; Hz (frequency)
; Don't change anything below!

struct_devicemode_size = 156
VarSetCapacity(device_mode, struct_devicemode_size, 0)

EncodeInteger(struct_devicemode_size, 2, &device_mode, 36)

success := DllCall("EnumDisplaySettings", "uint", 0, "uint", -1, "uint", &device_mode)

; DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY
EncodeInteger(0x00040000|0x00080000|0x00100000|0x00400000, 4, &device_mode, 40)

EncodeInteger(colorDepth, 4, &device_mode, 104)
EncodeInteger(screenWidth, 4, &device_mode, 108)
EncodeInteger(screenHeight, 4, &device_mode, 112)
EncodeInteger(refreshRate, 4, &device_mode, 120)

DllCall("ChangeDisplaySettings", "uint", &device_mode, "uint", 0)

_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Mon Mar 06, 2006 2:38 pm    Post subject: Reply with quote

Code:
EncodeInteger(struct_devicemode_size, 2, &device_mode, 36)


Here is problem. Stop in this line.
Back to top
PhiLho



Joined: 27 Dec 2005
Posts: 6787
Location: France (near Paris)

PostPosted: Mon Mar 06, 2006 3:30 pm    Post subject: Reply with quote

You need the EncodeInteger function given by shimanov in the first version of the script:
Code:
EncodeInteger( p_value, p_size, p_address, p_offset )
{
   loop, %p_size%
      DllCall( "RtlFillMemory"
         , "uint", p_address+p_offset+A_Index-1
         , "uint", 1
         , "uchar", ( p_value >> ( 8*( A_Index-1 ) ) ) & 0xFF )
}

_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Tue Mar 07, 2006 8:47 am    Post subject: Reply with quote

Thanks PhiLho & shimanov for help
Back to top
Guest






PostPosted: Fri Jan 19, 2007 3:14 pm    Post subject: Reply with quote

Can anyone verify that this code still works with the latest version of AHK?
(ahk ver 1.0.46. 06)

All seems to work for me, except all the entries in thefrequency
column are all "0".

Thanks
Back to top
PhiLho



Joined: 27 Dec 2005
Posts: 6787
Location: France (near Paris)

PostPosted: Fri Jan 19, 2007 4:12 pm    Post subject: Reply with quote

Works for me (1.0.46.06) out of the box. Hey, I can switch to 320x200, great! Very Happy
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Sat Jan 20, 2007 9:51 am    Post subject: Reply with quote

PhiLho wrote:
Works for me (1.0.46.06) out of the box. Hey, I can switch to 320x200, great! Very Happy


Thanks for the test. I guess this is just one of those "win98SE" problems.
I tried it on two computers with the same results: it does successfully change display modes, but always displays "0" in the frequency column. Crying or Very sad
Back to top
BoBo
Guest





PostPosted: Sat Jan 20, 2007 9:58 am    Post subject: Reply with quote

@Guest
please use a nick (you don't have to register for it). Thx. Cool
Back to top
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group