AutoHotkey Community

It is currently May 27th, 2012, 8:16 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 34 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Change Display Mode
PostPosted: February 28th, 2006, 8:43 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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 March 2nd, 2006, 5:16 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 1st, 2006, 12:26 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Very useful. Given the number of requests over the past two years, I know this is going to be a popular one!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 1st, 2006, 1:25 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 2nd, 2006, 3:05 pm 
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


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 2nd, 2006, 5:21 pm 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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 )


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 11:42 am 
Offline

Joined: February 14th, 2005, 10:54 am
Posts: 447
Location: Texas, Usa
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 :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2006, 10:39 am 
@shimanov
I steel not understand what is what parameters
do you writed code what is work whit 1200x124,32,60Hz?
thanks


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2006, 11:14 am 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
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)

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2006, 2:38 pm 
Code:
EncodeInteger(struct_devicemode_size, 2, &device_mode, 36)


Here is problem. Stop in this line.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2006, 3:30 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
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 )
}

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 7th, 2006, 8:47 am 
Thanks PhiLho & shimanov for help


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 19th, 2007, 3:14 pm 
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


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 19th, 2007, 4:12 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Works for me (1.0.46.06) out of the box. Hey, I can switch to 320x200, great! :-D

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 20th, 2007, 9:51 am 
PhiLho wrote:
Works for me (1.0.46.06) out of the box. Hey, I can switch to 320x200, great! :-D


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. :cry:


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 20th, 2007, 9:58 am 
@Guest
please use a nick (you don't have to register for it). Thx. 8)


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 34 posts ]  Go to page 1, 2, 3  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Aravind, Google Feedfetcher, Stigg and 12 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group