 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Tue Feb 28, 2006 8:43 am Post subject: Change Display Mode |
|
|
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 |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10666
|
Posted: Wed Mar 01, 2006 12:26 am Post subject: |
|
|
| 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 |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Wed Mar 01, 2006 1:25 am Post subject: |
|
|
| 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 |
|
 |
Guest
|
Posted: Thu Mar 02, 2006 3:05 pm Post subject: |
|
|
| 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
|
Posted: Thu Mar 02, 2006 5:21 pm Post subject: |
|
|
| 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 |
|
 |
Invalid User
Joined: 14 Feb 2005 Posts: 440 Location: Texas, Usa
|
Posted: Fri Mar 03, 2006 11:42 am Post subject: |
|
|
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  |
|
| Back to top |
|
 |
Guest
|
Posted: Mon Mar 06, 2006 10:39 am Post subject: |
|
|
@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)
|
Posted: Mon Mar 06, 2006 11:14 am Post subject: |
|
|
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 |
|
 |
Guest
|
Posted: Mon Mar 06, 2006 2:38 pm Post subject: |
|
|
| 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)
|
Posted: Mon Mar 06, 2006 3:30 pm Post subject: |
|
|
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 |
|
 |
Guest
|
Posted: Tue Mar 07, 2006 8:47 am Post subject: |
|
|
| Thanks PhiLho & shimanov for help |
|
| Back to top |
|
 |
Guest
|
Posted: Fri Jan 19, 2007 3:14 pm Post subject: |
|
|
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)
|
Posted: Fri Jan 19, 2007 4:12 pm Post subject: |
|
|
Works for me (1.0.46.06) out of the box. Hey, I can switch to 320x200, great!  _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
Guest
|
Posted: Sat Jan 20, 2007 9:51 am Post subject: |
|
|
| PhiLho wrote: | Works for me (1.0.46.06) out of the box. Hey, I can switch to 320x200, great!  |
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.  |
|
| Back to top |
|
 |
BoBo Guest
|
Posted: Sat Jan 20, 2007 9:58 am Post subject: |
|
|
@Guest
please use a nick (you don't have to register for it). Thx.  |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|